集合運算符用於合併多個查詢結果集,是 SQL 編寫中處理「並集、交集、差集」的利器。本文通過語法、去重規則、排序行為、列對應要求及實戰示例,全面解析四大運算符。
| 運算符 | 含義 | 去重 | 默認排序 | 典型場景 |
|---|---|---|---|---|
UNION | 並集 | 是 (排序去重) | 按第一列升序 | 合併多表數據,需唯一結果 |
UNION ALL | 並集 (含重複) | 否 (保留所有行) | 不排序 (按來源順序) | 高性能合併、日志審計、明細保留 |
INTERSECT | 交集 | 是 | 按第一列升序 | 找出兩集合共同記錄 |
MINUS | 差集 (第一集合 - 第二集合) | 是 | 按第一列升序 | 找出僅在第一集合存在的記錄 |
-- 假設表 A、B 結構相同 (id, name) -- 1. UNION 去重合併 SELECT id, name FROM tableA UNION SELECT id, name FROM tableB; -- 2. UNION ALL 保留重複 (性能最佳,無排序開銷) SELECT id, name FROM tableA UNION ALL SELECT id, name FROM tableB; -- 3. INTERSECT 交集 SELECT id, name FROM tableA INTERSECT SELECT id, name FROM tableB; -- 4. MINUS 差集 (在 A 中但不在 B 中) SELECT id, name FROM tableA MINUS SELECT id, name FROM tableB;
SELECT * FROM ( SELECT id, name FROM tableA UNION ALL SELECT id, name FROM tableB ) ORDER BY id DESC; -- 這樣才能自定義排序
SELECT * FROM tableA FULL OUTER JOIN tableB USING (id) -- 等價於 SELECT id, name FROM tableA UNION SELECT id, name FROM tableB; -- 僅當 name 也相同才等價
SELECT * FROM t1 UNION SELECT * FROM t2 INTERSECT SELECT * FROM t3 -- 等價於 (t1 UNION t2) INTERSECT t3 -- 建議用括號明確意圖 (Oracle 不支持括號,需用內聯視圖) SELECT * FROM ( SELECT * FROM t1 UNION SELECT * FROM t2 ) INTERSECT SELECT * FROM t3;
EXISTS/NOT EXISTS 或 JOIN 由優化器選擇 Hash/Anti Join。/*+ PARALLEL */ 提升大集合運算吞吐。集合運算符語義清晰、SQL 簡潔,但隱式排序去重 (除 UNION ALL) 在大數據量下代價高昂。實戰中:
UNION ALLMINUS / INTERSECTUNION