EXCEPT 運算子 (SQL EXCEPT Operator)
EXCEPT 運算子用來取得存在於第一個查詢結果但不存在於第二個查詢結果中的紀錄,也就是兩個結果集的「差集」。
如同 UNION 和 INTERSECT,EXCEPT 返回的結果也會自動去除重複的資料列。
EXCEPT 語法 (SQL EXCEPT Syntax)
SELECT column_name(s) FROM table_name1
EXCEPT
SELECT column_name(s) FROM table_name2;
兩個 SELECT 查詢所產生的欄位需要是相同的資料型別及順序。
EXCEPT 運算子查詢用法 (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 |
現在我們想查出有在台灣地區銷售但沒有在中國大陸地區銷售的產品,我們可以作一個 EXCEPT 查詢:
SELECT P_Name FROM products_taiwan
EXCEPT
SELECT P_Name FROM products_china;
查詢結果如下:
| P_Name |
|---|
| RAM |
因為 LCD 和 CPU 在 products_china 資料表中也有,所以被排除了,只剩下 RAM。
EXCEPT 的方向性
EXCEPT 是有方向性的,A EXCEPT B 與 B EXCEPT A 的結果不同:
-- 查出中國大陸有販售但台灣沒有的產品
SELECT P_Name FROM products_china
EXCEPT
SELECT P_Name FROM products_taiwan;
查詢結果:
| P_Name |
|---|
| Keyboard |
MySQL 中的替代方案
MySQL 目前還不支援 EXCEPT,可以使用 NOT IN 子查詢或 LEFT JOIN 來達到相同效果。
使用 NOT IN 子查詢:
SELECT P_Name FROM products_taiwan
WHERE P_Name NOT IN (SELECT P_Name FROM products_china);
使用 LEFT JOIN:
SELECT t.P_Name
FROM products_taiwan t
LEFT JOIN products_china c ON t.P_Name = c.P_Name
WHERE c.P_Name IS NULL;