查詢「沒有銷售 'GEO POSITIONING SYSTEM' 的部門」。
SELECT deptname FROM qdept WHERE deptname NOT IN (SELECT deptname FROM qsale WHERE itemname = 'Geo Positioning System')SELECT DISTINCT deptname FROM qsale WHERE itemname != 'Geo Positioning System'兩者結果完全不同,原因何在?
-- qsale 表數據
deptname | itemname
-----------|-------------------
銷售部 | Geo Positioning System -- 賣過 GPS
銷售部 | Laptop -- 也賣過筆記本
技術部 | Mouse -- 只賣過滑鼠
人事部 | (無記錄) -- 無任何銷售
{'銷售部'}deptname NOT IN ('銷售部')itemname != 'Geo Positioning System'銷售部-Laptop, 技術部-Mouse「沒有做過 X」 ≠ 「做過非 X」
若不想用 NOT IN (注意 NULL 值陷阱),推薦 NOT EXISTS 或 LEFT JOIN ... IS NULL:
-- 1. NOT EXISTS (標準、安全、性能好)
SELECT deptname
FROM qdept d
WHERE NOT EXISTS (
SELECT 1 FROM qsale s
WHERE s.deptname = d.deptname
AND s.itemname = 'Geo Positioning System'
);
-- 2. LEFT JOIN (直觀)
SELECT d.deptname
FROM qdept d
LEFT JOIN qsale s
ON d.deptname = s.deptname
AND s.itemname = 'Geo Positioning System'
WHERE s.deptname IS NULL;
NOT IN 子查詢結果集包含 NULL 時,整個條件返回 UNKNOWN (無結果)。永遠在子查詢加 WHERE col IS NOT NULL 或改用 NOT EXISTS。!= / <> 只能用於「存在非目標值」的場景,不能用於「完全不存在目標值」。NOT EXISTS) 通常比非關聯 NOT IN 執行計劃更優,尤其有索引時。