UNION 與集合運算
UNION — 合併查詢結果
比喻:UNION 就像把兩份名單合併 📋+📋
A 班的學生名單 + B 班的學生名單 = 全校名單。 UNION 就是把兩個 SELECT 的結果合併成一個。
UNION(去重複)
-- 合併兩班的學生(去除重複)
SELECT Name, Age FROM ClassA
UNION -- ← 合併並去重複
SELECT Name, Age FROM ClassB;
逐行解析:
SELECT Name, Age FROM ClassA -- 第一個查詢的結果
UNION -- 合併兩個結果,自動去除重複的列
SELECT Name, Age FROM ClassB -- 第二個查詢的結果
-- 欄位數量和型態必須一致!
UNION ALL(保留重複)
-- 合併兩班的學生(保留重複)
SELECT Name, Age FROM ClassA
UNION ALL -- ← 合併但保留重複
SELECT Name, Age FROM ClassB;
💡 UNION ALL 比 UNION 快,因為不需要去重複。 如果你確定沒有重複,或不在乎重複,用 UNION ALL。
UNION 的規則
-- ✅ 正確:欄位數量和型態一致
SELECT Name, Age FROM Students
UNION
SELECT Name, Age FROM Teachers;
-- ❌ 錯誤:欄位數量不同
SELECT Name, Age FROM Students
UNION
SELECT Name FROM Teachers; -- 少一個欄位!
-- ❌ 錯誤:型態不相容
SELECT Name, Age FROM Students
UNION
SELECT Name, Email FROM Teachers; -- Age 是數字,Email 是字串
INTERSECT — 交集
-- 同時選了數學和英文的學生
SELECT StudentId FROM Enrollments WHERE CourseId = 10
INTERSECT -- ← 只保留兩邊都有的
SELECT StudentId FROM Enrollments WHERE CourseId = 11;
EXCEPT — 差集
-- 選了數學但「沒選」英文的學生
SELECT StudentId FROM Enrollments WHERE CourseId = 10
EXCEPT -- ← 從第一組去掉第二組有的
SELECT StudentId FROM Enrollments WHERE CourseId = 11;
實用範例
-- 合併搜尋結果(標題或內容含關鍵字)
SELECT Id, Title, '標題符合' AS 來源
FROM Articles
WHERE Title LIKE '%SQL%'
UNION
SELECT Id, Title, '內容符合' AS 來源
FROM Articles
WHERE Content LIKE '%SQL%';
-- 統計各類別的訂單數和退貨數
SELECT '訂單' AS 類型, Category, COUNT(*) AS 數量
FROM Orders
GROUP BY Category
UNION ALL
SELECT '退貨' AS 類型, Category, COUNT(*) AS 數量
FROM Returns
GROUP BY Category
ORDER BY Category, 類型;
集合運算總覽
| 運算 | 效果 | 重複 |
|---|---|---|
UNION |
合併(去重) | 自動去除 |
UNION ALL |
合併(保留) | 保留重複 |
INTERSECT |
交集 | 兩邊都有 |
EXCEPT |
差集 | 第一組有、第二組沒有 |