Et kvalificeret gæt (i mangel på mere information):
NOT IN (...)
returnerer NULL
hvis nogen NULL
værdier er involveret, og den testede værdi er ikke på listen. Men kun TRUE
kvalificerer sig til en WHERE
klausul.
a NOT IN (b,c)
er omdannet til:
a <> ALL ('{b,c}'::sometype[])
svarende til:
(a <> b AND a <> c )
Hvis nogen af disse værdier (på begge sider af operatoren) er NULL
, får du:
(NULL AND FALSE)
Det er:
NULL
Og NULL
svarer til FALSE
i en WHERE
klausul. Kun TRUE
kvalificerer.
Dette har været kendt for at forårsage vantro hos brugere, der ikke er fortrolige med logik med tre værdier.
Brug IS DISTINCT FROM
eller NOT EXISTS
i stedet. Eller LEFT JOIN / IS NULL
.
Eksempel (mere gætværk)
I dette særlige tilfælde har du slet ikke brug for det belastede udtryk slet
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
)
Hvis du i al hemmelighed bruger en liste over værdier, der skal udelukkes, og som kan dele elementer med inklusionslisten:
...
AND (ta.task_status_type_id IN ( ... )) IS NOT TRUE
...
Eller du luger ud NULL-værdier.
Eller du undgår almindelige elementer i inklusions- og eksklusionslisten.