Tebakan yang terdidik (karena kurangnya informasi lebih lanjut):
NOT IN (...)
mengembalikan NULL
jika ada NULL
nilai terlibat dan nilai yang diuji tidak ada dalam daftar. Tapi hanya TRUE
memenuhi syarat dalam WHERE
klausa.
a NOT IN (b,c)
diubah menjadi:
a <> ALL ('{b,c}'::sometype[])
setara dengan:
(a <> b AND a <> c )
Jika ada dari nilai-nilai ini (di kedua sisi operator) adalah NULL
, Anda mendapatkan:
(NULL AND FALSE)
Yaitu:
NULL
Dan NULL
setara dengan FALSE
dalam WHERE
ayat. Hanya TRUE
memenuhi syarat.
Hal ini diketahui menyebabkan ketidakpercayaan pada pengguna yang tidak terbiasa dengan logika tri-nilai.
Gunakan IS DISTINCT FROM
atau NOT EXISTS
sebagai gantinya. Atau LEFT JOIN / IS NULL
.
Contoh (lebih banyak tebakan)
Dalam kasus khusus ini, Anda tidak memerlukan ekspresi yang dituduhkan sama sekali
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
)
Jika Anda diam-diam menggunakan daftar nilai yang akan dikecualikan yang dapat berbagi elemen dengan daftar penyertaan:
...
AND (ta.task_status_type_id IN ( ... )) IS NOT TRUE
...
Atau Anda membuang nilai NULL.
Atau Anda menghindari elemen umum dalam daftar penyertaan dan pengecualian.