199 votes

MySQL", PAS DANS" la requête

Je voulais exécuter une requête simple de jeter toutes les lignes de Table1 où la principale valeur de la colonne n'est pas présent dans une colonne d'une autre table (Table2).

J'ai essayé d'utiliser:

SELECT * FROM Table1 WHERE Table1.principal NOT IN Table2.principal

C'est au lieu de jeter une erreur de syntaxe. Recherche Google m'a conduit à des forums où les gens disaient que MySQL ne prend pas en charge NOT IN et quelque chose d'extrêmement complexe doit être utilisé. Est-ce vrai? Ou ai-je fait une horrible erreur?

333voto

Julien Lebosquain Points 20894

Pour l'utiliser, vous devez disposer d'un ensemble, utilisez cette syntaxe:

SELECT * FROM Table1 WHERE Table1.principal NOT IN (SELECT principal FROM table2)

170voto

Lukáš Lalinský Points 22537

La sous-requête option a déjà été répondu, mais note que, dans de nombreux cas, une LEFT JOIN peut être un moyen plus rapide pour ce faire:

SELECT table1.*
FROM table1 LEFT JOIN table2 ON table2.principal=table1.principal
WHERE table2.principal IS NULL

Si vous voulez vérifier plusieurs tables pour s'assurer qu'il n'est pas présent dans toutes les tables (comme dans SRKR du commentaire), vous pouvez utiliser ceci:

SELECT table1.*
FROM table1
LEFT JOIN table2 ON table2.name=table1.name
LEFT JOIN table3 ON table3.name=table1.name
WHERE table2.name IS NULL AND table3.name IS NULL

36voto

engin Points 350

PAS contre PAS contre une JOINTURE GAUCHE / NULL dans MySQL

MySQL, ainsi que tous les autres systèmes à l'exception de SQL Server, est en mesure d'optimiser LEFT JOIN / IS NULL de revenir FALSE dès que la valeur correspondante est trouvée, et c'est le seul système qui s'occupait du document ce comportement. [...] Depuis MySQL n'est pas capable d'utiliser HASH et MERGE des algorithmes de jointure, la seule ANTI JOIN il est capable de se l' NESTED LOOPS ANTI JOIN

[...]

Essentiellement, [NOT IN] est exactement le même plan que l' LEFT JOIN / IS NULL utilise, malgré le fait que ces plans sont exécutés par les différentes branches de code et ils semblent différents sur les résultats de l' EXPLAIN. Les algorithmes sont en fait la même chose en fait et les requêtes en même temps.

[...]

Il est difficile de dire exactement pourquoi [chute des performances lors de l'utilisation d' NOT EXISTS], puisque cette baisse est linéaire et ne semble pas dépendre de la distribution de données, le nombre de valeurs dans les deux tables, etc., tant que les deux champs sont indexés. Puisqu'il y a trois morceaux de code dans MySQL, qui comprend en particulier faire un travail, il est possible que le code responsable de l' EXISTS fait une sorte de une vérification supplémentaire qui prend du temps.

[...]

MySQL peut optimiser les trois méthodes pour faire une sorte de NESTED LOOPS ANTI JOIN. [...] Toutefois, ces trois méthodes de générer des trois régimes différents qui sont exécutées par trois différents morceaux de code. Le code qui s'exécute EXISTS prédicat est environ 30% moins efficace [...]

C'est pourquoi la meilleure façon de rechercher des valeurs manquantes dans MySQL à l'aide d'un LEFT JOIN / IS NULL ou NOT IN plutôt que d' NOT EXISTS.

(accentuation ajoutée)

7voto

Legna Points 141

Malheureusement, il semble être un problème avec MySql utilisation de "PAS DANS la" clause de l'écran-shoot ci-dessous montre la sous-option de requête de retour de mauvais résultats:

mysql> show variables like '%version%';
+-------------------------+------------------------------+
| Variable_name           | Value                        |
+-------------------------+------------------------------+
| innodb_version          | 1.1.8                        |
| protocol_version        | 10                           |
| slave_type_conversions  |                              |
| version                 | 5.5.21                       |
| version_comment         | MySQL Community Server (GPL) |
| version_compile_machine | x86_64                       |
| version_compile_os      | Linux                        |
+-------------------------+------------------------------+
7 rows in set (0.07 sec)

mysql> select count(*) from TABLE_A where TABLE_A.Pkey not in (select distinct TABLE_B.Fkey from TABLE_B );
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.07 sec)

mysql> select count(*) from TABLE_A left join TABLE_B on TABLE_A.Pkey = TABLE_B.Fkey where TABLE_B.Pkey is null;
+----------+
| count(*) |
+----------+
|      139 |
+----------+
1 row in set (0.06 sec)

mysql> select count(*) from TABLE_A where NOT EXISTS (select * FROM TABLE_B WHERE TABLE_B.Fkey = TABLE_A.Pkey );
+----------+
| count(*) |
+----------+
|      139 |
+----------+
1 row in set (0.06 sec)

mysql> 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X