sql >> Database teknologi >  >> RDS >> PostgreSQL

NOT IN i postgresql virker ikke

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.




  1. Overførsel af parametre til en JDBC PreparedStatement

  2. Hvordan kan jeg sikre, at en materialiseret visning altid er opdateret?

  3. Sådan får du alle fejl i alle SSIS-pakker i en løsning

  4. Tjek, om to valg er ækvivalente