2010-10-29 17 views
5

Estoy trabajando en un programa de seguimiento de entrenamiento y estoy en un punto en el que no puedo entender la consulta SQL.Consulta SQL: enumere todos los elementos en una tabla que no aparecen en otra tabla

Tengo 3 tablas: employees, trainingRecords, masterList.

employees y trainingRecords están relacionados a través del empID fkey.

trainingRecords y masterList están relacionados a través del TID fkey.

En este momento, la tabla de registros de entrenamiento está en blanco porque no se ha ingresado nada (todos los empleados no tienen capacitación).

Quiero llenar un cuadro de lista con todos los elementos de la lista maestra que no se incluyen en la tabla trainingRecords.

Desde la mesa trainingRecords está en blanco, se debe regresar lName, fName de la mesa y employeesdocName, docNumber para todas las entradas en la lista maestra.

Estoy perplejo. ¿Alguna sugerencia?

Respuesta

5

Supongo que desea mostrar a todos los empleados varias veces con los documentos de capacitación que aún no han hecho.

SELECT a.lName, a.fName, b.docNumber, b.docName 
FROM 
(SELECT e.lName, e.fName, t.TID 
FROM employees e 
LEFT JOIN trainingRecords t ON e.empID = t.empID 
) AS a, 
(SELECT m.docNumber, m.docName, t.TID 
FROM masterList m 
LEFT JOIN trainingRecords t ON m.TID = t.TID 
) AS b 
WHERE a.TID IS NULL OR b.TID IS NULL 
ORDER BY a.lName, b.docNumber 

resultados ejemplo:

lName  fName docNumber   docName 
Simpson Homer  1  Nuclear Physics for Dummies 
Simpson Homer  2  Nuclear Physics for Beginners 
Simpson Homer  3  Advanced Nuclear Physics 
Simpson Lisa  3  Advanced Nuclear Physics 
+0

esto funcionó al principio, pero luego agregué un registro y ahora sus tablas vacías que regresan – Sinaesthetic

+0

alteraron la cláusula where y añadieron otra columna a la parte b. Eso debería funcionar correctamente ahora :) – JumpingJezza

+0

booya allí está. Incluso fui capaz de separarlo lo suficiente como para recrearlo de memoria, gracias. – Sinaesthetic

3

Desea LEFT JOIN, en el lado izquierdo de la unión se encuentra la tabla que usted sabe que contendrá todo ya la derecha estará lo que está probando.

select masterList.* from masterList LEFT JOIN trainingRecords ON(masterList.TID = trainingRecords.TID) WHERE trainingRecords.TID IS NULL; 
+0

Terminé pensando en esto, pero ¿cómo consigo el nombre del empleado allí? – Sinaesthetic

0

bien, usted tiene que unirse las tres tablas con la tabla trainingRecords en el medio, ya que tiene las columnas necesarias para enlazar las otras dos mesas. Su consulta se verá algo como esto:

SELECT E.lName, E.fName, ML.docName, ML.docNumber FROM 
    (employees E LEFT OUTER JOIN trainingRecords TR ON E.empID = TR.empID) 
       RIGHT OUTER JOIN masterList ML ON ML.TID = TR.TID 
    WHERE TR.TID IS NULL 

¿Qué está pasando aquí?

Primero, estás haciendo una UNIÓN EXTERIOR IZQUIERDA de empleados y registros de entrenamiento. IZQUIERDA EXTERIOR es asegurar que todos los registros de los empleados aparezcan incluso si no hay coincidencia en los Registros de entrenamiento (que, por supuesto, no existen, ya que TrainingRecords no tiene datos).

Luego, está tomando los resultados de esa consulta y RIGHT OUTER ÚNASE a la lista maestra. El RIGHT OUTER garantiza que se incluirán todos los registros de la lista maestra, incluso si no hay coincidencias en los Registros de entrenamiento.

Finalmente, DONDE TR.TID IS NULL filtra cualquier registro que realmente coincida con cualquier registro (futuro) en los registros de entrenamiento.

+0

no estoy seguro de lo que sucedió, pero recibí un error que indicaba que la unión no era compatible. Aliasing? – Sinaesthetic

-1

Por qué no uso completo de Ingreso? Lo que uso es:

Select A.* from A Full Join B on A.ID = B.ID where B.ID is NULL 
+0

acaba de darse cuenta de que la unión completa tiene los mismos resultados que la combinación izquierda en este caso. –

Cuestiones relacionadas