एक शिक्षित अनुमान (अधिक जानकारी के अभाव में):
NOT IN (...)
रिटर्न NULL
अगर कोई NULL
मान शामिल हैं और परीक्षण किया गया मान सूची में नहीं है। लेकिन केवल TRUE
एक WHERE
. में अर्हता प्राप्त करता है खंड।
a NOT IN (b,c)
में बदल दिया जाता है:
a <> ALL ('{b,c}'::sometype[])
के बराबर:
(a <> b AND a <> c )
अगर कोई इन मानों में से (ऑपरेटर के दोनों ओर) NULL
. है , आपको मिलता है:
(NULL AND FALSE)
वह है:
NULL
और NULL
FALSE
. के बराबर है एक WHERE
. में खंड। केवल TRUE
अर्हता प्राप्त करता है।
यह त्रि-मूल्यवान तर्क से अपरिचित उपयोगकर्ताओं में अविश्वास पैदा करने के लिए जाना जाता है।
IS DISTINCT FROM
. का उपयोग करें या NOT EXISTS
बजाय। या LEFT JOIN / IS NULL
।
उदाहरण (अधिक अनुमान)
इस विशेष मामले में, आपको आरोपित अभिव्यक्ति की आवश्यकता नहीं है बिल्कुल
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
)
यदि आप बाहर रखे जाने वाले मानों की सूची का गुप्त रूप से उपयोग कर रहे हैं जो समावेशन सूची के साथ तत्वों को साझा कर सकते हैं:
...
AND (ta.task_status_type_id IN ( ... )) IS NOT TRUE
...
या आपने NULL मानों को हटा दिया है।
या आप समावेश और बहिष्करण सूची में सामान्य तत्वों से बचते हैं।