首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL 集合運算全解析:UNION、INTERSECT、EXCEPT(MINUS)語法與效能指南

     編輯:關於SqlServer

四大集合運算子

運算子語義重複行處理Oracle/標準 SQLSQL Server/PostgreSQL
UNION並集:兩結果集合併去重UNIONUNION
UNION ALL並集(含重複)保留所有UNION ALLUNION ALL
INTERSECT交集:同時存在於兩集合去重INTERSECTINTERSECT
EXCEPT / MINUS差集:在第一集合但不在第二去重MINUSEXCEPT

語法規則

SELECT col1, col2 FROM TableA
UNION [ALL] | INTERSECT | EXCEPT | MINUS
SELECT col1, col2 FROM TableB;

前置條件:

  • 兩查詢欄位數量相同
  • 對應位置欄位資料型別相容(隱含轉換或顯式 CAST)
  • ORDER BY 僅能放在最後一個查詢之後,且需使用別名或位置序數

效能特徵與優化

運算子典型執行計畫優化建議
UNION合併 → 排序/雜湊去重若確知無重複或可接受重複,改用 UNION ALL 省去去重成本
UNION ALL單純串流合併最快,無額外運算子
INTERSECT / EXCEPT排序/雜湊匹配 → 篩選確保 JOIN 欄位有索引;大表考慮 EXISTS/NOT EXISTS 改寫

實戰改寫範例

找出兩表皆有的客戶(交集)

-- 集合寫法
SELECT CustId FROM Customers_2023
INTERSECT
SELECT CustId FROM Customers_2024;

-- EXISTS 改寫(常更彈性)
SELECT CustId FROM Customers_2023 c
WHERE EXISTS (SELECT 1 FROM Customers_2024 WHERE CustId = c.CustId);

找出舊表有但新表無的產品(差集)

SELECT ProductId FROM Products_Old
EXCEPT  -- Oracle 用 MINUS
SELECT ProductId FROM Products_New;

-- NOT EXISTS 改寫
SELECT ProductId FROM Products_Old p
WHERE NOT EXISTS (SELECT 1 FROM Products_New WHERE ProductId = p.ProductId);

巢狀與多集合組合

SELECT * FROM A
UNION
(SELECT * FROM B
 INTERSECT
 SELECT * FROM C);

括號決定優先序,建議顯式加括號提升可讀性。

常見陷阱

  • NULL 語義: 集合運算視 NULL = NULL(同值),與標量比較 NULL=NULL 為 UNKNOWN 不同
  • 資料型別優先序: SELECT 1 UNION SELECT 'a' 可能隱含轉換導致溢位或計畫失效,建議顯式 CAST
  • ORDER BY 位置: 僅允許最終結果集排序,不可在中間查詢使用

總結

集合運算子是關係代數在 SQL 的直接映射,語意清晰、標準化程度高。核心取捨:**預設去重的 UNION/INTERSECT/EXCEPT vs 無去重的 UNION ALL**;大數據量下優先評估 EXISTS/NOT EXISTS 或 JOIN 改寫以利用索引與統計資訊。

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