PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

NOT IN dans postgresql ne fonctionne pas

Une supposition éclairée (faute d'informations supplémentaires) :

NOT IN (...) renvoie NULL le cas échéant NULL des valeurs sont impliquées et la valeur testée n'est pas dans la liste. Mais seulement TRUE se qualifie dans un WHERE clause.

a NOT IN (b,c)

est transformé en :

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

équivalent à :

(a <> b AND a <> c )

Si tout de ces valeurs (de part et d'autre de l'opérateur) est NULL , vous obtenez :

(NULL AND FALSE)

C'est :

NULL

Et NULL est équivalent à FALSE dans un WHERE clause. Seulement TRUE se qualifie.

Cela a été connu pour provoquer l'incrédulité chez les utilisateurs peu familiers avec la logique à trois valeurs.

Utilisez IS DISTINCT FROM ou NOT EXISTS Au lieu. Ou LEFT JOIN / IS NULL .

Exemple (plus de conjectures)

Dans ce cas particulier, vous n'avez pas besoin de l'expression incriminée du tout

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 vous utilisez secrètement une liste de valeurs à exclure qui pourraient partager des éléments avec la liste d'inclusion :

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

Ou vous éliminez les valeurs NULL.
Ou vous évitez les éléments communs dans la liste d'inclusion et d'exclusion.