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

ⅰ亾dé卋堺 提交于 2021-02-08 14:15:51

问题


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?


回答1:


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



回答2:


You want LEFT JOIN, on the left side of the join will be the table that you know will contain everything and on the right will be what you are testing against.

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



回答3:


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.




回答4:


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


来源:https://stackoverflow.com/questions/4048709/sql-query-list-all-items-in-one-table-that-do-not-appear-in-another-table

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!