web-dev-qa-db-fra.com

Comment sélectionner tous les enregistrements d'une table qui n'existent pas dans une autre table?

table1 (id, nom)
table2 (id, nom)

Requete:

SELECT name   
FROM table2  
-- that are not in table1 already
401
z-boss
SELECT t1.name
FROM table1 t1
LEFT JOIN table2 t2 ON t2.name = t1.name
WHERE t2.name IS NULL

Q: Que se passe-t-il ici?

A: Conceptuellement, nous sélectionnons toutes les lignes de table1 et pour chaque ligne, nous essayons de trouver une ligne dans table2. avec la même valeur pour la colonne name. Si aucune ligne de ce type n'existe, nous laissons simplement la partie table2 de notre résultat vide pour cette ligne. Ensuite, nous limitons notre sélection en sélectionnant uniquement les lignes du résultat où la ligne correspondante n'existe pas. Enfin, nous ignorons tous les champs de notre résultat à l’exception de la colonne name (celle que nous sommes sûrs d’exister, de table1).

Bien que cette méthode ne soit peut-être pas la plus performante possible dans tous les cas, elle devrait fonctionner dans pratiquement tous les moteurs de base de données essayant d'implémenter ANSI 92 SQL

739
Kris

Vous pouvez soit faire

SELECT name
FROM table2
WHERE name NOT IN
    (SELECT name 
     FROM table1)

ou

SELECT name 
FROM table2 
WHERE NOT EXISTS 
    (SELECT * 
     FROM table1 
     WHERE table1.name = table2.name)

Voir cette question pour 3 techniques pour accomplir ceci

209
froadie

Je n'ai pas assez de points de rep pour voter la deuxième réponse. Mais je ne suis pas d'accord avec les commentaires de la première réponse. La deuxième réponse:

SELECT name
FROM table2
WHERE name NOT IN
    (SELECT name 
     FROM table1)

Est loin plus efficace dans la pratique. Je ne sais pas pourquoi, mais je l’utilise avec plus de 800 000 disques et la différence est énorme avec l’avantage donné à la deuxième réponse postée ci-dessus. Juste mon 0,02 $

68
Tan Rezaei

C'est la théorie des ensembles pure que vous pouvez réaliser avec l'opération minus.

select id, name from table1
minus
select id, name from table2
36
Winter
SELECT <column_list>
FROM TABLEA a
LEFTJOIN TABLEB b 
ON a.Key = b.Key 
WHERE b.Key IS NULL;

enter image description here

https://www.cloudways.com/blog/how-to-join-two-tables-mysql/

18
Anuraj

Attention aux pièges. Si le champ Name dans Table1 contient des valeurs Null, des surprises vous attendent. Mieux vaut:

SELECT name
FROM table2
WHERE name NOT IN
    (SELECT ISNULL(name ,'')
     FROM table1)
14
user4872693

Voici ce qui a fonctionné le mieux pour moi.

SELECT *
FROM @T1
EXCEPT
SELECT a.*
FROM @T1 a
JOIN @T2 b ON a.ID = b.ID

C'était plus de deux fois plus rapide que toute autre méthode que j'ai essayée.

13
Bob

Vous pouvez utiliser EXCEPT dans mssql ou MINUS dans Oracle, ils sont identiques selon:

http://blog.sqlauthority.com/2008/08/07/sql-server-except-clause-in-sql-server-is-similar-to-minus-clause-in-Oracle/ =

8
Izzy

Ça marche bien pour moi

SELECT * 
FROM [dbo].[table1] t1
LEFT JOIN [dbo].[table2] t2 ON t1.[t1_ID] = t2.[t2_ID]
WHERE t2.[t2_ID] IS NULL
7
David Fawzy

Je vais republier (puisque je ne suis pas encore assez cool pour commenter) la réponse correcte ... au cas où quelqu'un penserait qu'il faudrait mieux l'expliquer.

SELECT temp_table_1.name
FROM original_table_1 temp_table_1
LEFT JOIN original_table_2 temp_table_2 ON temp_table_2.name = temp_table_1.name
WHERE temp_table_2.name IS NULL

Et j’ai vu la syntaxe dans FROM nécessiter des virgules entre les noms de table dans MySQL, mais dans sqlLite, elle semblait préférer l’espace.

En bout de ligne, lorsque vous utilisez des noms de variable incorrects, cela laisse des questions. Mes variables devraient avoir plus de sens. Et quelqu'un devrait expliquer pourquoi nous avons besoin d'une virgule ou non.

0
Adrian Roth

Voir requête:

SELECT * FROM Table1 WHERE
id NOT IN (SELECT 
        e.id
    FROM
        Table1 e
            INNER JOIN
        Table2 s ON e.id = s.id);

Conceptuellement, ce serait: Récupérer les enregistrements correspondants dans une sous-requête, puis dans la requête principale, extraire les enregistrements qui ne sont pas dans une sous-requête.

0
jawahar