MINUS 是 Oracle 的集合運算子,回傳「左側查詢結果集中存在、但右側查詢結果集中不存在」的列 (差集)。本文以建表、插資、查詢完整範例,說明 MINUS 行為規則、欄位對應要求、與 NOT IN/NOT EXISTS 的差異。
CREATE TABLE guotest1 (sName VARCHAR2(10), Gender VARCHAR2(10));
CREATE TABLE guotest2 (sName VARCHAR2(10), Gender VARCHAR2(10));
INSERT INTO guotest1 VALUES ('a','m');
INSERT INTO guotest1 VALUES ('b','m');
INSERT INTO guotest1 VALUES ('c','f');
INSERT INTO guotest1 VALUES ('d','f');
INSERT INTO guotest2 VALUES ('e','m');
INSERT INTO guotest2 VALUES ('f','m');
INSERT INTO guotest2 VALUES ('g','f');
INSERT INTO guotest2 VALUES ('h','f');
COMMIT;
SELECT * FROM guotest1 WHERE ROWNUM <= 4
MINUS
SELECT * FROM guotest1 WHERE ROWNUM <= 2;
-- 結果:
-- sName Gender
-- c f
-- d f
應用:取第 3-4 筆 (配合 ROWNUM 邏輯),或比對同表不同時期快照差異。
SELECT * FROM guotest1
MINUS
SELECT * FROM guotest2;
-- 結果:
-- sName Gender
-- a m
-- b m
-- c f
-- d f
guotest1 所有列在 guotest2 中均不存在,故全數回傳。若 guotest2 有 ('a','m'),則該列不會出現在結果中。
| 特性 | MINUS | NOT IN | NOT EXISTS |
|---|---|---|---|
| 語法 | 兩完整 SELECT | 子查詢單值/列表 | 相關子查詢 |
| 多欄位比較 | 原生支援 | 需 (col1,col2) NOT IN (...) (10g+) | 原生支援 |
| NULL 處理 | NULL=NULL 視為匹配 | 子查詢含 NULL → 全不匹配 (陷阱) | 正確處理 NULL |
| 去重 | 自動 | 否 (需 DISTINCT) | 否 (視外層查詢) |
| 效能 | 排序/雜湊集合運算 | 視子查詢優化 | 通常最優 (半連接) |
| 可讀性 | 集合思維直觀 | 直觀 | 略複雜 |
PGA_AGGREGATE_TARGET 足夠。NOT EXISTS 並確保關聯欄位有索引。SELECT pk FROM left MINUS SELECT pk FROM right 減少傳輸列寬。| 運算子 | 語意 | 去重 |
|---|---|---|
UNION | 並集 (左∪右) | 是 |
UNION ALL | 並集 (含重複) | 否 |
INTERSECT | 交集 (左∩右) | 是 |
MINUS | 差集 (左-右) | 是 |