Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MySQL:NOT IN com sub select não está funcionando como esperado?


Vou supor que há pelo menos um registro em sales_flat_order que satisfaça a condição status != 'holded' e cujo customer_email é NULL .

(NOT) IN é notoriamente complicado com NULL s, aqui está um exemplo.

Considere a seguinte consulta:
SELECT 1 WHERE 1 NOT IN (SELECT 2 UNION ALL SELECT 3)

Isso produz um registro com valor 1 , como esperado.

No entanto, se você alterar isso para:
SELECT 1 WHERE 1 NOT IN (SELECT 2 UNION ALL SELECT NULL)

Em seguida, a consulta produz um conjunto de resultados vazio. Este é um problema bem conhecido com (NOT) IN . Por esse motivo, você deve evitar essa sintaxe e usar (NOT) EXISTS em vez de. A consulta acima pode ser reescrita como:
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
)

Demonstração no DB Fiddle

Para sua consulta:
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'
);