J'ai deux tables avec la clé primaire de liaison dans la base de données et je souhaite trouver un ensemble disjoint entre elles. Par exemple,
Table1
contient des colonnes (ID, Name
) et des exemples de données:(1 ,John), (2, Peter), (3, Mary)
Table2
contient des colonnes (ID, Address
) et des exemples de données:(1, address2), (2, address2)
Alors, comment puis-je créer une requête SQL afin de pouvoir récupérer la ligne avec l'ID table1
qui n'est pas dans table2
. Dans ce cas, (3, Mary)
doit être retourné?
Ps. L'ID est la clé primaire de ces deux tables.
Merci d'avance.
sql
database
postgresql
johnklee
la source
la source
Réponses:
Essaye ça
la source
Utilisation
LEFT JOIN
la source
Il existe essentiellement 3 approches: que
not exists
,not in
etleft join / is null
.JOINT GAUCHE avec IS NULL
PAS DEDANS
N'EXISTE PAS
Quel est le meilleur? La réponse à cette question pourrait être mieux répartie entre les principaux fournisseurs de SGBDR spécifiques. D'une manière générale, il faut éviter d'utiliser
select ... where ... in (select...)
lorsque l'ampleur du nombre d'enregistrements dans la sous-requête est inconnue. Certains fournisseurs peuvent limiter la taille. Oracle, par exemple, a une limite de 1 000 . La meilleure chose à faire est d'essayer les trois et de montrer le plan d'exécution.Formulaire spécifiquement PostgreSQL, plan d'exécution
NOT EXISTS
etLEFT JOIN / IS NULL
sont les mêmes. Personnellement, je préfère l'NOT EXISTS
option car elle montre mieux l'intention. Après tout la sémantique est que vous voulez trouver les enregistrements dans A que ses pk n'existent pas dans B .Vieux mais toujours doré, spécifique à PostgreSQL cependant: https://explainextended.com/2009/09/16/not-in-vs-not-exists-vs-left-join-is-null-postgresql/
la source
Alternative rapide
J'ai effectué quelques tests (sur postgres 9.5) en utilisant deux tables avec ~ 2M lignes chacune. Cette requête ci-dessous a effectué au moins 5 * mieux que les autres requêtes proposées:
la source
En gardant à l'esprit les points soulevés dans le commentaire / lien de @John Woo ci-dessus, voici comment je le gérerais généralement:
la source
la source