2011-09-14 12 views
8

Usando MS Access. Lamento que el título sea vago; simplemente no sé exactamente cómo describir qué tipo de problema es, solo sé que necesito unir dos tablas o consultas para resolverlo.Acceda a la pregunta de la combinación SQL

Tengo una tabla OrgHistory que muestra qué organización cada persona (por ID) se unieron en una fecha determinada (que sólo puede ser un miembro de una org a la vez):

Person | Org | JoinDate 
----------------------- 
123 | abc | 3/2/2011 
456 | abc | 4/23/1925 
123 | def | 5/12/2011 

que también tienen una Activities tabla:

Person | Activity | ActivityDate 
-------------------------------- 
123 | eat  | 3/23/2011 
123 | sleep | 6/25/2011 
456 | walk  | 7/20/1985 

quiero averiguar, por cada registro en Activities, que la organización a la persona era un miembro de la fecha de la actividad. Estoy pensando que esto podría implicar convertir los valores JoinDate en un conjunto de rangos y coincidir con ActivityDate en el intervalo apropiado, pero estoy un poco confundido acerca de cómo diseñar la consulta en este caso - cómo creo rangos y comparo un valor individual a un rango?

No creo que partition() funcione porque no estoy tratando de mantener múltiples valores JoinDate en una cantidad conocida de cubos.

+0

estoy de acuerdo a su tabla 'OrgHistory' le falta un atributo' LeaveDate': se debería agregar una nueva columna 'LeaveDate' a su tabla base, agregar una clave secuenciada para asegurarse de que los periodos no se superpongan para la misma persona (sugerencia: necesita una restricción' CHECK'), luego restregar los datos ** una vez ** (@ Banjoe's consulta parece prometedor para esto). – onedaywhen

+0

+1 @onedaywhen - para usar una fecha de finalización en lugar de un booleano activo/no activo. Muchas personas no consideran tener que retroceder históricamente para encontrar una membresía. – JeffO

Respuesta

5

No puedo prometer esto es la forma más eficiente, pero funciona en el acceso a los datos de prueba que ya ha proporcionado:

SELECT a.person, a.activity, 
     (
     SELECT TOP 1 org 
      FROM orghistory AS o 
     WHERE o.person = a.person 
       AND o.joindate <= a.activitydate 
     ORDER 
      BY o.joindate DESC 
     ) AS Org 
    FROM activities AS a; 
+0

gracias! Una buena idea acerca de tomar la fecha de membresía superior que es <= la fecha de actividad, tiene mucho sentido. – sigil