Mysql
 sql >> Database >  >> RDS >> Mysql

MySQL:NOT IN con sub select non funziona come previsto?

Darò per scontato che ci sia almeno un record in sales_flat_order che soddisfa la condizione status != 'holded' e il cui customer_email è NULL .

(NOT) IN è notoriamente complicato con NULL s, ecco un esempio.

Considera la seguente query:

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

Questo produce un record con valore 1 , come previsto.

Tuttavia, se lo modifichi in:

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

Quindi la query produce un set di risultati vuoto. Questo è un problema ben noto con (NOT) IN . Per questo motivo, dovresti generalmente evitare questa sintassi e utilizzare (NOT) EXISTS invece. La query precedente potrebbe essere riscritta come:

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 su DB Fiddle

Per la tua domanda:

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