PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

NOT IN in postgresql non funziona

Un'ipotesi plausibile (per mancanza di ulteriori informazioni):

NOT IN (...) restituisce NULL se presente NULL i valori sono coinvolti e il valore testato non è nell'elenco. Ma solo TRUE si qualifica in un WHERE clausola.

a NOT IN (b,c)

viene trasformato in:

a <> ALL ('{b,c}'::sometype[])

equivalente a:

(a <> b AND a <> c )

Se qualsiasi di questi valori (su entrambi i lati dell'operatore) è NULL , ottieni:

(NULL AND FALSE)

Questo è:

NULL

E NULL è equivalente a FALSE in un WHERE clausola. Solo TRUE si qualifica.

Questo è noto per causare incredulità negli utenti che non hanno familiarità con la logica a tre valori.

Usa IS DISTINCT FROM o NOT EXISTS invece. Oppure LEFT JOIN / IS NULL .

Esempio (più congetture)

In questo caso particolare, non hai bisogno dell'espressione incriminata per niente

SELECT ta.task_id AS id
     , u.employee_id
     , ta.task_status_type_id
FROM   task_assignments ta
JOIN   users            u  ON u.id = ta.user_id
WHERE  ta.id IN (
   SELECT max(ta.id) AS id
   FROM   task_details     td
   JOIN   task_assignments ta USING (task_id)
   WHERE  td.developer_employee_id IS NULL
   AND    ta.task_type_id IN (6,7)
-- AND    ta.task_status_type_id IS DISTINCT FROM 10 -- just cruft
   AND    ta.task_status_type_id = 9                 -- this expression covers it
   GROUP  BY ta.task_id
   )

Se stai utilizzando segretamente un elenco di valori da escludere che potrebbero condividere elementi con l'elenco di inclusione:

... 
    AND    (ta.task_status_type_id IN ( ... )) IS NOT TRUE
...

Oppure elimini i valori NULL.
Oppure eviti gli elementi comuni nell'elenco di inclusione ed esclusione.