2010-05-20 13 views
7

Estoy buscando registros de acceso para cursos específicos. Necesito mostrar todos los cursos, incluso si no existen en la tabla de registros. De ahí la unión externa ... pero después de intentar (presumiblemente) todas las variaciones de LEFT OUTER, RIGHT OUTER, INNER y la colocación de las tablas dentro del código SQL, no pude obtener mi resultado.SQL Server 2005 RIGHT OUTER JOIN no funciona

Esto es lo que estoy corriendo:

SELECT (a.first_name+' '+a.last_name) instructor, 
      c.course_id, 
      COUNT(l.access_date) course_logins, 
      a.logins system_logins, 
      MAX(l.access_date) last_course_login, 
      a.last_login last_system_login 
FROM  lsn_logs l RIGHT OUTER JOIN courses c ON l.course_id = c.course_id, 
      accounts a 
WHERE  l.object_id = 'LOGIN' 
      AND c.course_type = 'COURSE' 
      AND c.course_id NOT LIKE '%TEST%' 
      AND a.account_rights > 2 
      AND l.user_id = a.username 
      AND ((a.first_name+' '+a.last_name) = c.instructor) 
GROUP BY c.course_id, 
      a.first_name, 
      a.last_name, 
      a.last_login, 
      a.logins, 
      c.instructor 
ORDER BY a.last_name, 
      a.first_name, 
      c.course_id, 
      course_logins DESC 

¿Es algo en el WHERE cláusula que me está impidiendo llegar course_id de que no existen en lsn_logs? ¿Es la forma en que me estoy uniendo a las mesas?

De nuevo, en resumen, quiero todos los ID de curso independientemente de su existencia en lsn_logs.

+0

en caso de que tal vez se busca en hacer una izquierda unirse a cursos de lsn_logs? – Shaded

+0

Estás uniendo cuentas con 'lsn_logs'. ¿Qué cuenta debería devolverse si no hay log_entry para un curso determinado? – Quassnoi

+0

@quassnoi - el instructor del curso – CheeseConQueso

Respuesta

2
SELECT...  
FROM courses c 
    INNER JOIN accounts a 
     ON (a.first_name+' '+a.last_name) = c.instructor 
    LEFT OUTER JOIN lsn_logs l 
     ON l.course_id = c.course_id 
     AND l.user_id = a.username 
     AND l.object_id = 'LOGIN' 
WHERE c.course_type = 'COURSE' 
    AND c.course_id NOT LIKE '%TEST%' 
    AND a.account_rights > 2 
    AND a.logins > 0 
GROUP BY... 
ORDER BY... 
+0

bueno - esto funciona igual que el mío, pero elimina toda la comprobación nula – CheeseConQueso

+0

su solución devuelve 1386 y la mía devuelve 1358 ... tengo que investigar eso – CheeseConQueso

8

¿Hay algo en la cláusula WHERE que me impide obtener course_id's que no existen en lsn_logs?

Sí, lo es.

Utiliza condiciones de igualdad en la cláusula WHERE que efectivamente filtra las filas NULL generadas por OUTER JOIN.

Actualización:

SELECT c.instructor, 
     c.course_id, 
     l.course_logins, 
     a.logins system_logins, 
     l.last_course_login, 
     a.last_login last_system_login 
FROM courses с 
JOIN accounts a 
ON  a.first_name + ' ' + a.last_name = c.instructor 
CROSS APPLY 
     (
     SELECT COALESCE(COUNT(access_date), 0) course_logins, 
       MAX(access_date) last_course_login 
     FROM lsn_logs l 
     WHERE l.object_id = 'LOGIN' 
       AND l.course_id = c.course_id 
       AND l.user_id = a.username 
     ) l 
WHERE c.course_type = 'COURSE' 
     AND c.course_id NOT LIKE '%TEST%' 
     AND a.account_rights > 2 
ORDER BY 
     a.last_name, 
     a.first_name, 
     c.course_id, 
     course_logins DESC 
+0

eso es lo que pensé ... creo que la respuesta de joe r's y/o de oromars podría trabajo, pero gracias por la aclaración – CheeseConQueso

+0

@cheese: ¿podría responder la pregunta en mi comentario a su publicación? – Quassnoi

2

Para ampliar buena respuesta de Quassnoi, para la combinación externa a trabajar podría cambiar:

AND l.user_id = a.username 

Para:

AND (l.user_id is null OR l.user_id = a.username) 
+0

las tablas de cuentas y cursos siempre tendrán registros que coincidan, pero los lsn_logs estarán vacíos para algunos cursos y/o cuentas – CheeseConQueso

+0

null/o combos en la tabla lsn_logs necesitaron atención – CheeseConQueso

+0

@CheeseConQueso: respuesta editada por lo que solo comprueba null en la tabla lsn_logs – Andomar

1

El SQL ¡Servidor 2005 RIGHT OUTER JOIN ciertamente funciona! :)

¿Qué pasa con lo siguiente (he hecho algunos supuestos) ?:

eliminar

AND l.user_id = a.username 

y cambiar los puntos de unión a

dbo.courses c 
LEFT OUTER JOIN lsn_logs l 
ON c.course_id = l.course_id 
LEFT OUTER JOIN accounts a 
ON l.user_id = a.username 

y añadir algunos cheques nulos para lsn_logs y campos de cuentas, como:

(l.object_id IS NULL OR l.object_id = 'LOGIN') 
+0

Por cierto, ¡tienes una foto muy inquietante! :) –

+0

es inquietante en el buen sentido, aunque ... gracias por la sugerencia, creo que su combinación externa doble podría funcionar – CheeseConQueso

+0

aún el mismo resultado establecido ... Veo a dónde iba con esto aunque – CheeseConQueso

0

Esto terminó trabajando

Los cheques nulos que Joe R sugerido se hizo cargo del problema que se menciona Quassnoi

SELECT (a.first_name+' '+a.last_name) instructor, 
      c.course_id, 
      COUNT(l.access_date) course_logins, 
      a.logins system_logins, 
      MAX(l.access_date) last_course_login, 
      a.last_login last_system_login 
FROM  lsn_logs l RIGHT OUTER JOIN courses c ON l.course_id = c.course_id, 
      accounts a 
WHERE  (l.object_id IS NULL OR l.object_id = 'LOGIN') 
      AND c.course_type = 'COURSE' 
      AND c.course_id NOT LIKE '%TEST%' 
      AND a.account_rights > 2 
      AND (l.user_id = a.username OR l.user_id IS NULL) 
      AND ((a.first_name+' '+a.last_name) = c.instructor) 
      AND a.logins > 0 
GROUP BY c.course_id, 
      a.first_name, 
      a.last_name, 
      a.last_login, 
      a.logins, 
      c.instructor 
ORDER BY a.last_name, 
      a.first_name, 
      c.course_id, 
      course_logins DESC 
+0

por cierto - probablemente exista una forma mejor de hacerlo todo dentro de la sección 'FROM' ... publique cualquier modificación – CheeseConQueso

+0

presente y error" número de error del proveedor de datos sqlclient 8153 "pero todavía devuelve los resultados ... tengo que mirar en ese – CheeseConQueso