Una conjetura (por falta de más información):
NOT IN (...)
devuelve NULL
si alguno NULL
hay valores involucrados y el valor probado no está en la lista. Pero solo TRUE
califica en un WHERE
cláusula.
a NOT IN (b,c)
se transforma en:
a <> ALL ('{b,c}'::sometype[])
equivalente a:
(a <> b AND a <> c )
Si cualquiera de estos valores (a cada lado del operador) es NULL
, obtienes:
(NULL AND FALSE)
Eso es:
NULL
Y NULL
es equivalente a FALSE
en un WHERE
cláusula. Solo TRUE
califica.
Se sabe que esto causa desconfianza en los usuarios que no están familiarizados con la lógica de tres valores.
Usar IS DISTINCT FROM
o NOT EXISTS
en cambio. O LEFT JOIN / IS NULL
.
Ejemplo (más conjeturas)
En este caso particular, no necesita la expresión incriminada en absoluto
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
)
Si está utilizando en secreto una lista de valores para ser excluidos que podrían compartir elementos con la lista de inclusión:
...
AND (ta.task_status_type_id IN ( ... )) IS NOT TRUE
...
O elimina los valores NULL.
O evita los elementos comunes en la lista de inclusión y exclusión.