2010-10-29 12 views
5

Sto lavorando a un programma di monitoraggio della formazione e sono a un punto in cui non riesco a capire la query SQL.Query SQL: elenca tutti gli elementi in una tabella che non compaiono in un'altra tabella

Ho 3 tabelle: employees, trainingRecords, masterList.

employees e trainingRecords sono collegati tramite il tasto f. empID.

trainingRecords e masterList sono collegati tramite il tasto f. TID.

In questo momento la tabella dei record di allenamento è vuota perché non è stato inserito nulla (tutti i dipendenti non hanno una formazione).

Desidero compilare una casella di riepilogo con tutti gli elementi nella lista principale non presenti nella tabella trainingRecords.

Poiché la tabella trainingRecords è vuota, va tornando lName, fName dalla tabella employees e docName, docNumber per tutte le voci della lista principale.

Sono perplesso. Eventuali suggerimenti?

risposta

5

Suppongo che tu voglia visualizzare tutti i dipendenti più volte con i documenti di formazione che non hanno ancora fatto.

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 

esempio i risultati:

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

questo ha funzionato all'inizio, ma poi ho aggiunto un record e ora le sue tabelle vuote di ritorno – Sinaesthetic

+0

hanno modificato la clausola where e aggiunto un'altra colonna alla parte b. Che dovrebbe funzionare correttamente ora :) – JumpingJezza

+0

booya lì è. Sono stato persino in grado di distinguerlo abbastanza da ricrearlo dalla memoria, grazie. – Sinaesthetic

3

Si desidera SINISTRA UNIRE, sul lato sinistro del join sarà la tabella che sapete conterrà tutto e sulla destra sarà ciò che si sta testando contro.

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

ho finito per capire questo molto, ma come faccio a ottenere il nome del dipendente in là? – Sinaesthetic

0

Va bene, è necessario unire tutte e tre le tabelle con la tabella trainingRecords nel mezzo perché ha le colonne necessarie per collegare le altre due tabelle. La tua ricerca sarà simile a questa:

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 

Cosa sta succedendo qui?

In primo luogo, si sta eseguendo un'operazione LEFT OUTER JOIN di dipendenti e trainingRecords. Il LEFT OUTER deve garantire che tutti i record dei dipendenti vengano visualizzati anche se non vi è alcuna corrispondenza in trainingRecords (che ovviamente non esiste poiché trainingRecords non ha dati).

Quindi, si stanno prendendo i risultati di tale query e RIGHT OUTER si unisce a masterlist. The RIGHT OUTER garantisce che tutti i record della lista master saranno inclusi anche se non ci sono corrispondenze in trainingRecords.

Infine, WHERE TR.TID IS NULL filtra tutti i record che effettivamente corrispondevano a qualsiasi (futuro) record in trainingRecords.

+0

non so cosa sia successo ma ho ricevuto un errore che indica che il join non era supportato. Aliasing? – Sinaesthetic

-1

perché non utilizzare completa aderire? Quello che uso è:

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

ti rendi conto che il join completo ha gli stessi risultati del join sinistro in questo caso. –

Problemi correlati