Một phỏng đoán có học (vì thiếu thêm thông tin):
NOT IN (...)
trả về NULL
nếu có NULL
các giá trị có liên quan và giá trị được kiểm tra không có trong danh sách. Nhưng chỉ TRUE
đủ điều kiện trong một WHERE
mệnh đề.
a NOT IN (b,c)
được chuyển đổi thành:
a <> ALL ('{b,c}'::sometype[])
tương đương với:
(a <> b AND a <> c )
Nếu bất kỳ trong số các giá trị này (ở một trong hai bên của toán tử) là NULL
, bạn nhận được:
(NULL AND FALSE)
Đó là:
NULL
Và NULL
tương đương với FALSE
trong một WHERE
mệnh đề. Chỉ TRUE
đủ điều kiện.
Điều này đã được biết là gây ra sự tin tưởng ở những người dùng không quen với logic ba giá trị.
Sử dụng IS DISTINCT FROM
hoặc NOT EXISTS
thay thế. Hoặc LEFT JOIN / IS NULL
.
Ví dụ (phỏng đoán thêm)
Trong trường hợp cụ thể này, bạn không cần biểu thức bao gồm hoàn toàn
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
)
Nếu bạn đang bí mật sử dụng danh sách các giá trị bị loại trừ có thể chia sẻ các phần tử với danh sách bao gồm:
...
AND (ta.task_status_type_id IN ( ... )) IS NOT TRUE
...
Hoặc bạn loại bỏ các giá trị NULL.
Hoặc bạn tránh các yếu tố phổ biến trong danh sách bao gồm và loại trừ.