sql >> Databasteknik >  >> RDS >> PostgreSQL

NOT IN i postgresql fungerar inte

En kvalificerad gissning (i brist på mer information):

NOT IN (...) returnerar NULL om någon NULL värden är inblandade och det testade värdet finns inte i listan. Men bara TRUE kvalificerar sig i en WHERE klausul.

a NOT IN (b,c)

omvandlas till:

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

motsvarande:

(a <> b AND a <> c )

Om någon av dessa värden (på båda sidor om operatorn) är NULL , du får:

(NULL AND FALSE)

Det är:

NULL

Och NULL motsvarar FALSE i en WHERE klausul. Endast TRUE kvalificerar.

Detta har varit känt för att orsaka misstro hos användare som inte är bekanta med logik med tre värden.

Använd IS DISTINCT FROM eller NOT EXISTS istället. Eller LEFT JOIN / IS NULL .

Exempel (mer gissningar)

I det här specifika fallet behöver du inte överhuvudtaget det inkriminerade uttrycket

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
   )

Om du i hemlighet använder en lista med värden som ska uteslutas som kan dela element med inkluderingslistan:

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

Eller så rensar du bort NULL-värden.
Eller så undviker du vanliga element i inkluderings- och exkluderingslistan.




  1. Hur man delar upp frågefönster i SQL Server Management Studio (SSMS) - SQL Server / TSQL självstudie del 13

  2. mysql motsvarande datatyper

  3. Motsvarar explode() för att arbeta med strängar i MySQL

  4. Använd Räkna för att hitta antalet förekomster