首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle MINUS 集合運算詳解:差集邏輯與實戰範例

     編輯:Oracle 資料庫相關知識

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;

二、核心規則

  1. 欄位數、型別、順序必須一致:兩側 SELECT 列表對位比較。
  2. 回傳列來源固定為左側:右側僅作比較依據,其資料不出現在結果中。
  3. 自動去重:結果集不含重複列 (集合語意)。
  4. NULL 值視為相等:雙方同位置為 NULL 視為匹配,不會出現在差集中。

三、實戰範例

範例 1:同表自差 (分頁/分批邏輯)

SELECT * FROM guotest1 WHERE ROWNUM <= 4
MINUS
SELECT * FROM guotest1 WHERE ROWNUM <= 2;

-- 結果:
-- sName  Gender
-- c      f
-- d      f

應用:取第 3-4 筆 (配合 ROWNUM 邏輯),或比對同表不同時期快照差異。

範例 2:跨表差集

SELECT * FROM guotest1
MINUS
SELECT * FROM guotest2;

-- 結果:
-- sName  Gender
-- a      m
-- b      m
-- c      f
-- d      f

guotest1 所有列在 guotest2 中均不存在,故全數回傳。若 guotest2 有 ('a','m'),則該列不會出現在結果中。

四、MINUS vs NOT IN vs NOT EXISTS

特性MINUSNOT INNOT EXISTS
語法兩完整 SELECT子查詢單值/列表相關子查詢
多欄位比較原生支援需 (col1,col2) NOT IN (...) (10g+)原生支援
NULL 處理NULL=NULL 視為匹配子查詢含 NULL → 全不匹配 (陷阱)正確處理 NULL
去重自動否 (需 DISTINCT)否 (視外層查詢)
效能排序/雜湊集合運算視子查詢優化通常最優 (半連接)
可讀性集合思維直觀直觀略複雜

五、效能建議

  • 大量資料 MINUS 會觸發排序 (SORT UNIQUE) 或雜湊 (HASH SET OPERATION),確保 PGA_AGGREGATE_TARGET 足夠。
  • 若右側資料量極大,考慮改寫為 NOT EXISTS 並確保關聯欄位有索引。
  • 僅需比對主鍵時,建議 SELECT pk FROM left MINUS SELECT pk FROM right 減少傳輸列寬。

六、UNION / UNION ALL / INTERSECT 快速對照

運算子語意去重
UNION並集 (左∪右)是
UNION ALL並集 (含重複)否
INTERSECT交集 (左∩右)是
MINUS差集 (左-右)是
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved