MINUS 運算子 (SQL MINUS Operator)
當 MINUS 運算子結合了兩個 SELECT 查詢語句,它會將(第一個查詢結果集)減去(同時存在於第一個查詢結果集與第二個查詢結果集的資料紀錄),然後返回其結果。簡單來說,MINUS 就是在做「集合的差集」:只保留出現在第一個查詢、卻沒有出現在第二個查詢的資料。
MINUS 語法 (SQL MINUS Syntax)
SELECT column_name(s) FROM table1
MINUS
SELECT column_name(s) FROM table2;
MINUS 實際範例
假設我們有一個 customers 客戶資料表,以及一個 orders 訂單資料表,想找出「已經註冊、但還沒下過任何訂單」的客戶。
customers 資料表:
| customer_id | name |
|---|---|
| 1 | 張小明 |
| 2 | 李小華 |
| 3 | 王大同 |
| 4 | 陳美麗 |
orders 資料表:
| order_id | customer_id |
|---|---|
| 101 | 1 |
| 102 | 3 |
| 103 | 1 |
用 MINUS 找出「有註冊卻沒下單」的客戶:
SELECT customer_id FROM customers
MINUS
SELECT customer_id FROM orders;
查詢結果:
| customer_id |
|---|
| 2 |
| 4 |
customers 有 1、2、3、4;orders 裡出現過的是 1 和 3,相減之後就得到 2 和 4,也就是李小華和陳美麗還沒下過訂單。要注意 orders 裡 customer_id = 1 出現了兩次,但 MINUS 會自動去除重複,所以結果不受影響。
MySQL 沒有 MINUS 怎麼辦?(NOT IN 與 LEFT JOIN)
MINUS 主要用於 Oracle 資料庫。MySQL 與 SQL Server 並不支援 MINUS(PostgreSQL 則是用 EXCEPT,用法相同)。在 MySQL 中,可以用下面兩種寫法達到一樣的效果。
方法一:使用 NOT IN
SELECT customer_id FROM customers
WHERE customer_id NOT IN (SELECT customer_id FROM orders);
方法二:使用 LEFT JOIN 搭配 IS NULL
SELECT c.customer_id
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id
WHERE o.customer_id IS NULL;
兩種寫法的結果都和 MINUS 相同,會得到 2 和 4。小提醒:使用 NOT IN 時,如果子查詢的欄位可能包含 NULL,整個查詢有可能回傳空結果;遇到這種情況,建議改用 NOT EXISTS 或上面的 LEFT JOIN 寫法會比較安全。
使用 MINUS 的注意事項
- 兩個 SELECT 的欄位數量必須相同,且對應欄位的資料型別要相容。
- MINUS 會自動去除重複資料(效果等同於 DISTINCT)。
- 結果的欄位名稱以第一個 SELECT 為準。
- 各資料庫語法不同:Oracle 用 MINUS、PostgreSQL 用 EXCEPT、MySQL 與 SQL Server 則改用 NOT IN 或 LEFT JOIN。
延伸閱讀
- SQL UNION
- SQL INTERSECT
- SQL 教學
- SQL SELECT
- SQL WHERE
- SQL JOIN
- SQL IN
- SQL EXISTS
- SQL Subquery
- SQL 聚合函數
留言功能已關閉。