简体   繁体   中英

SQL query: list all items in one table that do not appear in another table

I'm working on a training tracker program and I'm at a point where I can't figure out the SQL query.

I have 3 tables: employees, trainingRecords, masterList .

employees and trainingRecords are related through the empID fkey.

trainingRecords and masterList are related through the TID fkey.

Right now the training records table is blank because nothing has been entered (all employees have no training).

I want to populate a listbox with all of the items in the masterList that are unaccounted for in the trainingRecords table.

Since the trainingRecords table is blank, it should be returning lName, fName from the employees table and docName, docNumber for all entries in the master list.

I'm stumped. Any suggestions?

I'm assuming you want to display all employees multiple times with the training documents they have not done yet.

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

example results:

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

您想要LEFT JOIN,在连接的左侧将是您知道将包含所有内容的表,而右侧将是您正在测试的内容。

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

Okay, you have to JOIN all three tables with the trainingRecords table in the middle because it has the columns necessary to link the other two tables. Your query will look something like this:

 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

What's happening here?

First, you're doing a LEFT OUTER JOIN of employees and trainingRecords. The LEFT OUTER is to ensure that all the records from employees show up even if there's no match in trainingRecords (which of course don't exist since trainingRecords has no data at all).

Then, you're taking the results of that query and RIGHT OUTER JOINing them to masterList. The RIGHT OUTER guarantees that all masterList records will be included even if there are no matches in trainingRecords.

Finally, WHERE TR.TID IS NULL filters out any records that actually matched any (future) records in trainingRecords.

Why not use Full Join? What I use is:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM