Il me semble que vous pouvez faire la même chose dans une requête SQL en utilisant soit NOT EXISTS, NOT IN ou LEFT JOIN WHERE IS NULL. Par exemple:
SELECT a FROM table1 WHERE a NOT IN (SELECT a FROM table2)
SELECT a FROM table1 WHERE NOT EXISTS (SELECT * FROM table2 WHERE table1.a = table2.a)
SELECT a FROM table1 LEFT JOIN table2 ON table1.a = table2.a WHERE table1.a IS NULL
Je ne suis pas sûr que toute la syntaxe soit correcte, mais ce sont les techniques générales que j'ai vues. Pourquoi choisirais-je d'utiliser l'un plutôt que l'autre? Les performances diffèrent-elles ...? Lequel de ceux-ci est le plus rapide / le plus efficace? (Si cela dépend de la mise en œuvre, quand utiliserais-je chacun d'eux?)
EXISTS
clause. Vous pouvez revenir*
,NULL
ou autre: tout cela sera optimisé.SELECT
etFROM
. Et*
c'est juste plus facile à taper. Oui,SQL
cela ressemble à un langage naturel, mais il est analysé et exécuté par une machine, une machine programmée. Ce n'est pas qu'il va soudainement s'introduire dans votre armoire et crier "Arrêtez de demander les champs supplémentaires dans uneEXISTS
requête parce que j'en ai marre de les analyser et de les jeter!". C'est vraiment OK avec un ordinateur.Réponses:
NOT IN vs NOT EXISTS vs LEFT JOIN / IS NULL: SQL Server
NOT IN vs NOT EXISTS vs LEFT JOIN / IS NULL: PostgreSQL
NOT IN vs NOT EXISTS vs LEFT JOIN / IS NULL: Oracle
NOT IN vs NOT EXISTS vs LEFT JOIN / IS NULL: MySQL
En un mot:
NOT IN
est un peu différent: il ne correspond jamais s'il n'y en a qu'un seulNULL
dans la liste.En
MySQL
,NOT EXISTS
est un peu moins efficaceDans
SQL Server
,LEFT JOIN / IS NULL
est moins efficaceDans
PostgreSQL
,NOT IN
est moins efficaceEn
Oracle
, les trois méthodes sont identiques.la source
table1 .a
contientNULL
laEXISTS
requête ne renverra pas cette ligne mais laNOT IN
requête sera sitable2
vide. NOT IN vs NOT EXISTS Nullable Columns: SQL ServerNULL NOT IN ()
évalue à vrai (pasNULL
), tout commeNOT EXISTS (NULL = column)
NOT EXISTS
retournera toujours la ligne maisNOT IN
ne le fera que si la sous-requête ne renvoie aucune ligne.Si la base de données est bonne pour optimiser la requête, les deux premiers seront transformés en quelque chose de proche du troisième.
Pour des situations simples comme celles que vous interrogez, il devrait y avoir peu ou pas de différence, car elles seront toutes exécutées en tant que jointures. Dans les requêtes plus complexes, la base de données peut ne pas être en mesure de créer une jointure à partir des requêtes
not in
etnot exists
. Dans ce cas, les requêtes seront beaucoup plus lentes. D'un autre côté, une jointure peut également mal fonctionner s'il n'y a pas d'index pouvant être utilisé, donc ce n'est pas parce que vous utilisez une jointure que vous êtes en sécurité. Vous devrez examiner le plan d'exécution de la requête pour savoir s'il peut y avoir des problèmes de performances.la source
En supposant que vous évitiez les nulls, ce sont tous des moyens d'écrire une anti-jointure aide de SQL standard.
Une omission évidente est l'équivalent en utilisant
EXCEPT
:Notez que dans Oracle, vous devez utiliser l'
MINUS
opérateur (sans doute un meilleur nom):En parlant de syntaxe propriétaire, il peut également y avoir des équivalents non standard qui méritent d'être étudiés en fonction du produit que vous utilisez, par exemple
OUTER APPLY
dans SQL Server (quelque chose comme):la source
Lorsqu'il est nécessaire d'insérer des données dans une table avec une clé primaire multi-champs, considérez qu'il sera beaucoup plus rapide (j'ai essayé dans Access mais je pense dans n'importe quelle base de données) de ne pas vérifier "qu'il n'existe pas d'enregistrements avec de telles valeurs dans la table", - plutôt simplement insérer dans la table, et les enregistrements excédentaires (par la clé) ne seront pas insérés deux fois.
la source
La perspective des performances évite toujours d'utiliser des mots-clés inverses tels que NOT IN, NOT EXISTS, ... Parce que pour vérifier les éléments inverses, le SGBD doit parcourir tous les éléments disponibles et supprimer la sélection inverse.
la source
NOT
?