Come escludere le righe che non si uniscono a un'altra tabella?


87

Ho due tabelle, una ha la chiave primaria, l'altra l'ha come chiave esterna.

Voglio estrarre i dati dalla tabella primaria, solo se la tabella secondaria non ha una voce contenente la sua chiave. Una sorta di opposto di un semplice inner join, che restituisce solo le righe che si uniscono tramite quella chiave.

Risposte:


274

testo alternativo

SELECT <select_list> 
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key
WHERE B.Key IS NULL

Immagine completa di join testo alternativo

Da aticle: http://www.codeproject.com/KB/database/Visual_SQL_Joins.aspx


9
finalmente! perché non li hanno nei libri di testo e perché i miei docenti all'università non li hanno ?! hanno usato le peggiori spiegazioni possibili al mondo, non lontanamente vicine a queste!
pythonian29033

5
Questo è oro. Odio scrivere un commento che non abbia contenuto ma elogi espansivi, ma dai! Questa è una risposta fantastica. Grazie, @Pranay Rana.
0xbe5077ed il

1
Per favore spiegami, perché B.Key IS NULLma siamo ancora paragonabili A.Key = B.Key?
Do Nhu Vy

1
@DoNhuVy semplice, il confronto è nella clausola "ON", in un join LEFT o RIGHT se non c'è una riga corrispondente, viene unita una riga con tutti i NULL, dopodiché si verifica che IS NULL per sapere che non esiste una riga corrispondente . (Questo funziona, a proposito, solo se il campo che stai testando NON è NULL, cioè non può avere NULL per qualche altro motivo)
Gregory Magarshak

Sto usando la seguente query: SELECT A. * FROM #PurgeFilesListNew A FULL OUTER JOIN #DoNotPurgeFilesListNew B SU A.JobFileId = B.JobFileId AND A.AccountID = B.AccountID WHERE A.JobFileId È NULL O B.JobFileId È NULL E A.AccountID È NULL O B.AccountID È NULL Fondamentalmente, sto confrontando due valori nella clausola "ON". Funziona correttamente, ma la query restituisce una riga nulla per quelle righe che non corrispondono. Come risolverlo? Per favore
aiutatemi

10
SELECT
   *
FROM
   primarytable P
WHERE
   NOT EXISTS (SELECT * FROM secondarytable S
     WHERE
         P.PKCol = S.FKCol)

In generale , (NOT) EXISTSè una scelta migliore allora (NOT) INo(LEFT) JOIN


beh, non ha pubblicato quale DBRMS viene utilizzato, tuttavia in MySql LEFT JOINsupera le prestazioniNOT EXIST
The Scrum Meister

@ The Scrum Meister: ho detto più velocemente? Cerca IN vs EXISTS vs JOIN per scoprire le differenze semantiche e logiche ...
gbn

@gbn Scusa, ho pensato che con "scelta migliore" intendevi più veloce. Puoi quindi spiegare in che modo è una scelta migliore? Explinextended.com/2009/09/18/…
The Scrum Meister

1
@ The Scrum Meister: in genere, qualsiasi tipo di JOIN potrebbe richiedere un DISTINCT. NOT IN con un null nell'elenco restituisce false. IN / EXISTS si comportano allo stesso modo. Tuttavia, l'unico costrutto "sicuro" è (NON) ESISTE a meno che non ti piaccia l'incoerenza
gbn


4

usa un join sinistro "non esiste":

SELECT p.*
FROM primary_table p LEFT JOIN second s ON p.ID = s.ID
WHERE s.ID IS NULL

4

Un'altra soluzione è:

SELECT * FROM TABLE1 WHERE id NOT IN (SELECT id FROM TABLE2)

3
SELECT P.*
FROM primary_table P
LEFT JOIN secondary_table S on P.id = S.p_id
WHERE S.p_id IS NULL

2
Ho una domanda .. se stiamo usando la condizione P.key = S.keye poi diciamo where S.key IS NULL, allora anche P.key non diventa nullo?
Somjit

2

Se vuoi selezionare le colonne dalla Prima tabella "che sono presenti anche nella Seconda tabella, allora in questo caso puoi anche usare EXCEPT. In questo caso, anche i nomi delle colonne possono essere diversi ma il tipo di dati dovrebbe essere lo stesso.

Esempio:

select ID, FName
from FirstTable
EXCEPT
select ID, SName
from SecondTable

0

Questo è stato utile da utilizzare in COGNOS perché la creazione di un'istruzione SQL "Non in" in Cognos era consentita, ma l'esecuzione richiedeva troppo tempo. Avevo codificato manualmente la tabella A in modo che si unisse alla tabella B in Cognos come A.key "non in" B.key, ma la query richiedeva troppo tempo / non restituiva risultati dopo 5 minuti.

Per chiunque altro stia cercando una soluzione "NON IN" in Cognos, ecco cosa ho fatto. Creare una query che unisce le tabelle A e B con un LEFT JOIN in Cognos selezionando il tipo di collegamento: tabella A. La chiave ha valori da "0 a N" nella tabella B, quindi ha aggiunto un filtro (che corrispondono alle clausole Where) per: tabella B .Key è NULL.

Correva veloce e mi piaceva.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.