En kvalificerad gissning (i brist på mer information):
NOT IN (...)
returnerar NULL
om någon NULL
värden är inblandade och det testade värdet finns inte i listan. Men bara TRUE
kvalificerar sig i en WHERE
klausul.
a NOT IN (b,c)
omvandlas till:
a <> ALL ('{b,c}'::sometype[])
motsvarande:
(a <> b AND a <> c )
Om någon av dessa värden (på båda sidor om operatorn) är NULL
, du får:
(NULL AND FALSE)
Det är:
NULL
Och NULL
motsvarar FALSE
i en WHERE
klausul. Endast TRUE
kvalificerar.
Detta har varit känt för att orsaka misstro hos användare som inte är bekanta med logik med tre värden.
Använd IS DISTINCT FROM
eller NOT EXISTS
istället. Eller LEFT JOIN / IS NULL
.
Exempel (mer gissningar)
I det här specifika fallet behöver du inte överhuvudtaget det inkriminerade uttrycket
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
)
Om du i hemlighet använder en lista med värden som ska uteslutas som kan dela element med inkluderingslistan:
...
AND (ta.task_status_type_id IN ( ... )) IS NOT TRUE
...
Eller så rensar du bort NULL-värden.
Eller så undviker du vanliga element i inkluderings- och exkluderingslistan.