INTERSECT 運算子 (SQL INTERSECT Operator)
INTERSECT 運算子用於返回兩個查詢結果的交集,也就是同時存在於兩個結果集中的記錄。只有當一筆記錄在第一個查詢和第二個查詢中都出現時,它才會被包含在最終結果中。
集合運算比較
| 運算子 | 邏輯概念 | 說明 |
|---|---|---|
| UNION | OR (聯集) | 存在於任一結果集的記錄 |
| INTERSECT | AND (交集) | 同時存在於兩個結果集的記錄 |
| EXCEPT / MINUS | 差集 | 存在於第一個但不存在於第二個結果集的記錄 |
INTERSECT 語法 (Syntax)
SELECT column_list FROM table1
INTERSECT
SELECT column_list FROM table2;
使用 INTERSECT 的條件:
- 每個 SELECT 語句必須有相同數量的欄位。
- 對應的欄位必須有相容的資料型別。
- 結果集會自動去除重複記錄。
INTERSECT 用法範例 (Example)
products_taiwan 資料表 (台灣地區銷售產品):
| P_Id | P_Name |
|---|---|
| 1 | LCD |
| 2 | CPU |
| 3 | RAM |
products_china 資料表 (中國大陸地區銷售產品):
| P_Id | P_Name |
|---|---|
| 1 | Keyboard |
| 2 | CPU |
| 3 | LCD |
範例: 查詢在台灣和中國大陸都有銷售的產品。
SELECT P_Name FROM products_taiwan
INTERSECT
SELECT P_Name FROM products_china;
結果:
| P_Name |
|---|
| LCD |
| CPU |
只有 LCD 和 CPU 同時出現在兩個資料表中,所以只返回這兩筆記錄。
INTERSECT 運作圖解
products_taiwan: products_china:
┌─────────────────┐ ┌─────────────────┐
│ LCD, CPU, RAM │ │ Keyboard, CPU, │
│ │ │ LCD │
└─────────────────┘ └─────────────────┘
INTERSECT 結果:
┌─────────────────┐
│ LCD, CPU │ ← 兩邊都有的
└─────────────────┘
INTERSECT 與多個欄位
當 INTERSECT 應用於多個欄位時,只有所有欄位值都完全相同的記錄才會被視為匹配:
SELECT P_Id, P_Name FROM products_taiwan
INTERSECT
SELECT P_Id, P_Name FROM products_china;
這個查詢只會返回 P_Id 和 P_Name 都相同的記錄。根據上面的資料,結果會是空的,因為雖然 LCD 在兩邊都有,但它們的 P_Id 不同 (台灣是 1,中國是 3)。
MySQL 中的替代方案
⚠️ 注意: MySQL 不支援
INTERSECT運算子。但可以使用其他方法達到相同效果。
方法 1:使用 INNER JOIN
SELECT DISTINCT t.P_Name
FROM products_taiwan t
INNER JOIN products_china c ON t.P_Name = c.P_Name;
方法 2:使用 IN 子查詢
SELECT DISTINCT P_Name
FROM products_taiwan
WHERE P_Name IN (SELECT P_Name FROM products_china);
方法 3:使用 EXISTS
SELECT DISTINCT P_Name
FROM products_taiwan t
WHERE EXISTS (
SELECT 1 FROM products_china c WHERE c.P_Name = t.P_Name
);
實際應用場景
1. 找出共同客戶
找出同時購買過產品 A 和產品 B 的客戶:
SELECT Customer_Id FROM orders WHERE Product = 'A'
INTERSECT
SELECT Customer_Id FROM orders WHERE Product = 'B';
2. 資料比對
找出兩個系統中都存在的記錄:
SELECT Email FROM system1_users
INTERSECT
SELECT Email FROM system2_users;
3. 權限檢查
找出同時擁有多個權限的使用者:
SELECT User_Id FROM user_permissions WHERE Permission = 'READ'
INTERSECT
SELECT User_Id FROM user_permissions WHERE Permission = 'WRITE';
INTERSECT 與 DISTINCT
INTERSECT 會自動對結果進行去重處理,效果類似於 SELECT DISTINCT。如果原始資料有重複記錄,INTERSECT 的結果中每個唯一值只會出現一次。
資料庫支援
| 資料庫 | 支援 INTERSECT |
|---|---|
| PostgreSQL | ✅ 支援 |
| SQL Server | ✅ 支援 |
| Oracle | ✅ 支援 |
| SQLite | ✅ 支援 |
| MySQL | ❌ 不支援 (需使用替代方案) |