| 運算子 | 語義 | 重複行處理 | Oracle/標準 SQL | SQL Server/PostgreSQL |
|---|---|---|---|---|
| UNION | 並集:兩結果集合併 | 去重 | UNION | UNION |
| UNION ALL | 並集(含重複) | 保留所有 | UNION ALL | UNION ALL |
| INTERSECT | 交集:同時存在於兩集合 | 去重 | INTERSECT | INTERSECT |
| EXCEPT / MINUS | 差集:在第一集合但不在第二 | 去重 | MINUS | EXCEPT |
SELECT col1, col2 FROM TableA
UNION [ALL] | INTERSECT | EXCEPT | MINUS
SELECT col1, col2 FROM TableB;
前置條件:
| 運算子 | 典型執行計畫 | 優化建議 |
|---|---|---|
| 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);
括號決定優先序,建議顯式加括號提升可讀性。
SELECT 1 UNION SELECT 'a' 可能隱含轉換導致溢位或計畫失效,建議顯式 CAST集合運算子是關係代數在 SQL 的直接映射,語意清晰、標準化程度高。核心取捨:**預設去重的 UNION/INTERSECT/EXCEPT vs 無去重的 UNION ALL**;大數據量下優先評估 EXISTS/NOT EXISTS 或 JOIN 改寫以利用索引與統計資訊。