SELECT * O N'EXISTE PAS

94

Je pense que je vais dans le bon sens avec celui-ci ... Veuillez rester avec moi car mon SQL n'est pas le meilleur

J'essaie d'interroger une base de données pour tout sélectionner dans une table où certaines cellules n'existent pas dans une autre. Cela n'a pas beaucoup de sens mais j'espère que ce morceau de code

SELECT * from employees WHERE NOT EXISTS (SELECT name FROM eotm_dyn)

Donc, fondamentalement, j'ai un tableau avec une liste d'employés et leurs coordonnées. Puis un autre tableau avec quelques autres détails, y compris leur nom. Là où il n'y a pas de nom dans la table eotm_dyn, ce qui signifie qu'il n'y a pas d'entrée pour eux, je voudrais voir exactement qui ils sont, ou en d'autres termes, voir ce qui manque exactement.

La requête ci-dessus ne renvoie rien, mais je sais qu'il manque 20 noms, donc je n'ai évidemment pas bien compris.

Quelqu'un peut-il aider?

Ciaran
la source

Réponses:

160

Vous n'avez pas rejoint la table dans votre requête.

Votre requête d'origine ne renverra toujours rien à moins qu'il n'y ait aucun enregistrement eotm_dyn, auquel cas elle renverra tout.

En supposant que ces tables doivent être jointes employeeID, utilisez ce qui suit:

SELECT  *
FROM    employees e
WHERE   NOT EXISTS
        (
        SELECT  null 
        FROM    eotm_dyn d
        WHERE   d.employeeID = e.id
        )

Vous pouvez joindre ces tables avec un LEFT JOINmot-clé et filtrer les NULL's, mais ce sera probablement moins efficace que d'utiliser NOT EXISTS.

Quassnoi
la source
30
J'ai besoin de "WHERE NOT EXISTS" deux fois par an, et j'oublie toujours comment l'utiliser exactement. Merci - cet exemple sera maintenant mis en signet.
Mateng
1
Quelqu'un pourrait-il s'il vous plaît donner une référence pour "LEFT JOIN + NULL filter is less efficient than NOT EXISTS"? Cela peut être évident, mais je n'ai jamais vu cela dans la documentation. Merci.
toni07
2
@ toni07 En fait, c'est une légende. LEFT JOIN gagne. expliqueextended.com/2009/09/18/… .. Le blog de Quassnoi est toujours une ressource utile.
Kaii
comment utiliserais-je cela dans une clause HAVING? akagroup by X having exist [row with employeeID = e.id]
phil294
@blauhirn: juste comme ça
Quassnoi
83
SELECT * FROM employees WHERE name NOT IN (SELECT name FROM eotm_dyn)

OU

SELECT * FROM employees WHERE NOT EXISTS (SELECT * FROM eotm_dyn WHERE eotm_dyn.name = employees.name)

OU

SELECT * FROM employees LEFT OUTER JOIN eotm_dyn ON eotm_dyn.name = employees.name WHERE eotm_dyn IS NULL
Jour de Robin
la source
1
NB! NOT INne fonctionne pas comme prévu si namea des nullvaleurs. Regardez à partir de 36min 20sec dans la vidéo SESSION: 10 techniques de réglage des requêtes que chaque programmeur SQL devrait connaître (Kevin Kline, Aaron Bertrand) .
hlovdal le
12

Vous pouvez effectuer une jointure à gauche et affirmer que la colonne jointe est NULL.

Exemple:

SELECT * FROM employees a LEFT JOIN eotm_dyn b on (a.joinfield=b.joinfield) WHERE b.name IS NULL
Mike Tunnicliffe
la source
7
SELECT * from employees
WHERE NOT EXISTS (SELECT name FROM eotm_dyn)

Ne renvoie jamais aucun enregistrement à moins qu'il ne eotm_dynsoit vide. Vous avez besoin d'une sorte de critères sur SELECT name FROM eotm_dyncomme

SELECT * from employees
WHERE NOT EXISTS (
    SELECT name FROM eotm_dyn WHERE eotm_dyn.employeeid = employees.employeeid
)

en supposant que les deux tables sont liées par une relation de clé étrangère. À ce stade, vous pouvez utiliser une variété d'autres options, y compris une jointure à gauche. L'optimiseur les traitera généralement de la même manière dans la plupart des cas, cependant.

Cade Roux
la source
4

Vous pouvez également jeter un œil à cette question connexe . Cet utilisateur a signalé que l'utilisation d'une jointure offrait de meilleures performances que l'utilisation d'une sous-requête.

André Miller
la source