Mysql
 sql >> Base de données >  >> RDS >> Mysql

MySQL :NOT IN avec la sous-sélection ne fonctionne pas comme prévu ?

Je ferai l'hypothèse qu'il y a au moins un enregistrement dans sales_flat_order qui satisfait la condition status != 'holded' et dont customer_email est NULL .

(NOT) IN est notoirement délicat avec NULL s, voici un exemple.

Considérez la requête suivante :

SELECT 1 WHERE 1 NOT IN (SELECT 2 UNION ALL SELECT 3)

Cela donne un enregistrement avec la valeur 1 , comme prévu.

Cependant, si vous changez cela en :

SELECT 1 WHERE 1 NOT IN (SELECT 2 UNION ALL SELECT NULL)

Ensuite, la requête produit un jeu de résultats vide. Il s'agit d'un problème bien connu avec (NOT) IN . Pour cette raison, vous devriez généralement éviter cette syntaxe et utiliser (NOT) EXISTS Au lieu. La requête ci-dessus pourrait être réécrite comme :

SELECT 1 a
FROM (SELECT 1 a) t1
WHERE NOT EXISTS (
    SELECT 1
    FROM (SELECT 2 a UNION ALL SELECT NULL) t2
    WHERE t1.a = t2.a
)

Démo sur DB Fiddle

Pour votre requête :

SELECT customer_email 
FROM sales_flat_order s
WHERE NOT EXISTS (
    SELECT 1
    FROM sales_flat_order s1
    WHERE s1.customer_email = s.customer_email AND s.status != 'holded'
);