sql >> Databáze >  >> RDS >> PostgreSQL

NOT IN v postgresql nefunguje

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í.




  1. Vkládání do Oracle Nested Table v Javě

  2. Jak vybrat více než 1 záznam za den?

  3. SQL Server Azure / 2022 Database Ledger Tables z Linuxu.

  4. Řešení pro ORA-00997:nelegální použití datového typu LONG