INTERSECT 運算子 (SQL INTERSECT Operator)

INTERSECT 運算子用於返回兩個查詢結果的交集,也就是同時存在於兩個結果集中的記錄。只有當一筆記錄在第一個查詢和第二個查詢中都出現時,它才會被包含在最終結果中。

集合運算比較

運算子邏輯概念說明
UNIONOR (聯集)存在於任一結果集的記錄
INTERSECTAND (交集)同時存在於兩個結果集的記錄
EXCEPT / MINUS差集存在於第一個但不存在於第二個結果集的記錄

INTERSECT 語法 (Syntax)

SELECT column_list FROM table1
INTERSECT
SELECT column_list FROM table2;

使用 INTERSECT 的條件:

  1. 每個 SELECT 語句必須有相同數量的欄位
  2. 對應的欄位必須有相容的資料型別
  3. 結果集會自動去除重複記錄。

INTERSECT 用法範例 (Example)

products_taiwan 資料表 (台灣地區銷售產品):

P_IdP_Name
1LCD
2CPU
3RAM

products_china 資料表 (中國大陸地區銷售產品):

P_IdP_Name
1Keyboard
2CPU
3LCD

範例: 查詢在台灣和中國大陸都有銷售的產品。

SELECT P_Name FROM products_taiwan
INTERSECT
SELECT P_Name FROM products_china;

結果:

P_Name
LCD
CPU

只有 LCDCPU 同時出現在兩個資料表中,所以只返回這兩筆記錄。

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_IdP_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❌ 不支援 (需使用替代方案)