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

Oracle 兩表交集查詢兩大法:INTERSECT 與 IN 子查詢效能對比

     編輯:Oracle 資料庫相關知識

場景:找出兩張表相同的資料列

表 A:CODE (PK), NAME
表 B:STUDENT_CODE (PK), STUDENT_NAME, SCORE

資料:
A: ('1101','韓甲'), ('1102','丁乙')
B: ('1101','韓甲',99), ('1102','丁乙',89), ('1103','徐靜',94)

方法一:INTERSECT 集合運算子(推薦)

SELECT code, name FROM A
INTERSECT
SELECT student_code, student_name FROM B;
  • 自動比對**所有選取欄位**,欄位數量、型態、順序必須完全一致
  • 返回兩查詢結果集的**交集**(去重)
  • 語意清晰、SQL 簡潔、優化器易產生高效計劃 (HASH/SORT UNIQUE)

圖 1:INTERSECT 查詢結果

方法二:多重 IN 子查詢(傳統寫法)

SELECT code, name FROM A
WHERE A.code IN (SELECT student_code FROM B)
  AND A.name IN (SELECT student_name FROM B)
ORDER BY A.code;
  • 每個比較欄位需一個 IN 子查詢,欄位多時 SQL 膨脹
  • 語意為「A 的 code 在 B 中 **且** A 的 name 在 B 中」,**非逐列組合比對**,可能產生笛卡兒積式誤判(如 B 有 code=1101 name=甲、code=1102 name=乙,A 有 code=1101 name=乙 會被誤選)
  • 效能通常較差:多子查詢執行或轉為多重 JOIN

圖 2:IN 子查詢結果 (此範例資料下結果相同)

關鍵差異總結

維度INTERSECT多重 IN
語意正確性逐列組合比對 (Tuple-level)單獨欄位獨立比對 (Column-level),易誤判
SQL 簡潔度單一關鍵字需 N 個 IN 子查詢
效能通常優 (集合運算優化)視轉換計劃而定,通常較慢
去重行為自動 DISTINCT不去重,需自行處理
適用版本Oracle 7.3+所有版本

延伸:MINUS (差集) 與 UNION/UNION ALL

-- A 有但 B 沒有
SELECT * FROM A MINUS SELECT * FROM B;

-- 合併 (去重)
SELECT * FROM A UNION SELECT * FROM B;

-- 合併 (不去重,效能最好)
SELECT * FROM A UNION ALL SELECT * FROM B;

最佳實務建議

  1. **首選 INTERSECT / MINUS / UNION** 進行集合運算,語意精確、優化器友善
  2. 需保留重複列用 UNION ALL 並自行處理去重
  3. 避免多重 IN/EXISTS 模擬 Tuple 比較,除非版本極舊不支援集合運算子
  4. 大量資料集合運算時,確認雙方欄位型態完全一致 (隱式轉型會殺效能)

集合運算子是 SQL 標準的強大武器,INTERSECT 解決「兩表共同資料」是教科書級用法。拋棄多重 IN 的模糊語意與效能隱憂,擁抱標準集合思維。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved