views:

54

answers:

3

I'm working on a training tracker program and I'm at a point where I cant 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.

Im stumped. Any suggestions?

A: 

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; 
Suroot
i ended up figuring this much out, but how do i get the employee name in there?
Sinaesthetic
A: 

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.

Larry Lustig
not sure what happened but i got an error stating the join was not supported. Aliasing?
Sinaesthetic
A: 

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
JumpingJezza
this worked at first, but then i added a record and now its returning empty tables
Sinaesthetic
altered the where clause and added another column to part b. That should work properly now :)
JumpingJezza
booya there it is. I was even able to pick it apart enough to recreate it from memory, thanks.
Sinaesthetic