Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL:NOT IN mit Unterauswahl funktioniert nicht wie erwartet?

Ich gehe davon aus, dass es mindestens einen Datensatz in sales_flat_order gibt das die Bedingung status != 'holded' erfüllt und dessen customer_email ist NULL .

(NOT) IN ist notorisch schwierig mit NULL s, hier ist ein Beispiel.

Betrachten Sie die folgende Abfrage:

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

Dies ergibt einen Datensatz mit dem Wert 1 , wie erwartet.

Wenn Sie das jedoch ändern in:

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

Dann erzeugt die Abfrage eine leere Ergebnismenge. Dies ist ein bekanntes Problem mit (NOT) IN . Aus diesem Grund sollten Sie diese Syntax generell vermeiden und (NOT) EXISTS verwenden stattdessen. Die obige Abfrage könnte wie folgt umgeschrieben werden:

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
)

Demo auf DB Fiddle

Für Ihre Anfrage:

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'
);