Vzdělaný odhad (pro nedostatek dalších informací):
NOT IN (...)
vrátí NULL
pokud existuje NULL
hodnoty jsou zahrnuty a testovaná hodnota není v seznamu. Ale pouze TRUE
kvalifikuje se v WHERE
doložka.
a NOT IN (b,c)
se transformuje na:
a <> ALL ('{b,c}'::sometype[])
ekvivalentní:
(a <> b AND a <> c )
Pokud nějaké z těchto hodnot (na obou stranách operátoru) je NULL
, získáte:
(NULL AND FALSE)
To je:
NULL
A NULL
je ekvivalentní FALSE
v WHERE
doložka. Pouze TRUE
kvalifikuje.
Je známo, že to způsobuje nedůvěru u uživatelů, kteří nejsou obeznámeni s trojhodnotovou logikou.
Použijte IS DISTINCT FROM
nebo NOT EXISTS
namísto. Nebo LEFT JOIN / IS NULL
.
Příklad (více dohadů)
V tomto konkrétním případě inkriminovaný výraz vůbec nepotřebujete
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
)
Pokud tajně používáte seznam hodnot k vyloučení, které by mohly sdílet prvky se seznamem zahrnutí:
...
AND (ta.task_status_type_id IN ( ... )) IS NOT TRUE
...
Nebo vyřadíte hodnoty NULL.
Nebo se vyhnete společným prvkům v seznamu zahrnutí a vyloučení.