MINUS 運算子 (SQL MINUS Operator)
MINUS 運算子是 Oracle 資料庫中用於計算差集的運算子。它返回存在於第一個查詢結果但不存在於第二個查詢結果中的記錄。
💡 注意:
MINUS與EXCEPT功能完全相同,只是名稱不同。MINUS是 Oracle 專用的關鍵字,而EXCEPT是 SQL 標準中定義的關鍵字 (被 SQL Server、PostgreSQL、SQLite 等採用)。
MINUS 語法 (Syntax)
SELECT column_list FROM table1
MINUS
SELECT column_list FROM table2;
使用 MINUS 的條件:
- 每個 SELECT 語句必須有相同數量的欄位。
- 對應的欄位必須有相容的資料型別。
- 結果集會自動去除重複記錄。
- 結果集的欄位名稱會依據第一個 SELECT 查詢。
MINUS 用法範例 (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
MINUS
SELECT P_Name FROM products_china;
結果:
| P_Name |
|---|
| RAM |
LCD 和 CPU 在兩個表中都存在,所以被排除。只有 RAM 是台灣獨有的產品。
MINUS 的方向性
⚠️ 重要: MINUS 是有方向性的!
A MINUS B和B MINUS A的結果不同。
範例: 查詢在中國有銷售但在台灣沒有銷售的產品。
SELECT P_Name FROM products_china
MINUS
SELECT P_Name FROM products_taiwan;
結果:
| P_Name |
|---|
| Keyboard |
MINUS vs EXCEPT 對照表
| 特性 | MINUS | EXCEPT |
|---|---|---|
| 功能 | 差集運算 | 差集運算 |
| Oracle | ✅ 支援 | ❌ 不支援 |
| SQL Server | ❌ 不支援 | ✅ 支援 |
| PostgreSQL | ❌ 不支援 | ✅ 支援 |
| SQLite | ❌ 不支援 | ✅ 支援 |
| MySQL | ❌ 不支援 | ❌ 不支援 |
MySQL 中的替代方案
⚠️ 注意: MySQL 不支援
MINUS運算子。請參考EXCEPT文章中的替代方案:
使用 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;
實際應用場景
1. 找出獨有的產品
找出只在特定區域銷售的產品:
-- 只在台灣銷售的產品
SELECT Product_Id FROM products_taiwan
MINUS
SELECT Product_Id FROM products_global;
2. 比對資料差異
找出兩個資料集之間的差異:
-- 上週有但本週沒有的活躍用戶
SELECT User_Id FROM active_users_last_week
MINUS
SELECT User_Id FROM active_users_this_week;
3. 確認資料完整性
找出主表中有但明細表中沒有的記錄:
SELECT Order_Id FROM orders
MINUS
SELECT DISTINCT Order_Id FROM order_details;
多個 MINUS 連用
可以連續使用多個 MINUS:
SELECT P_Name FROM products_all
MINUS
SELECT P_Name FROM products_taiwan
MINUS
SELECT P_Name FROM products_china;
這會返回在 products_all 中存在,但不在 products_taiwan 且不在 products_china 中的產品。
搭配 ORDER BY
ORDER BY 子句必須放在整個查詢的最後:
SELECT P_Name FROM products_taiwan
MINUS
SELECT P_Name FROM products_china
ORDER BY P_Name;