🧾SQL CASE WHEN 判斷錯誤?完整解析資料欄位邏輯與常見錯誤(工程師實戰教學)
一個常見的資料問題:為什麼 SQL 查出來的結果不對?
在資料分析或資料庫開發中,工程師常會遇到一種情況:
SQL 語法沒有錯,但查出來的結果卻不符合預期。
這通常不是語法問題,而是邏輯設計錯誤。
其中最常見的來源,就是 CASE WHEN 條件判斷順序。
什麼是 CASE WHEN?
在 SQL 中,CASE WHEN 可以理解為:
如果符合某個條件 → 回傳某個值,否則回傳其他值
簡單來說就是 SQL 的 if-else。
例如:
SELECT
CASE
WHEN score >= 90 THEN 'Excellent'
WHEN score >= 60 THEN 'Pass'
ELSE 'Fail'
END AS Result
FROM StudentScore
邏輯意思是:
| 條件 | 回傳 |
|---|---|
| 分數 ≥ 90 | Excellent |
| 分數 ≥ 60 | Pass |
| 其他 | Fail |
CASE WHEN 有一個非常重要的特性
SQL 的 CASE 是 由上往下判斷。
只要符合第一個條件,就會停止判斷。
例如:
CASE
WHEN value > 10 THEN 'A'
WHEN value > 5 THEN 'B'
END
如果 value = 20
結果會是:
A
因為第一條就符合。
實際開發情境:資料欄位需要動態切換
在某些資料系統中,會出現多種來源的資料,例如:
| 欄位 | 說明 |
|---|---|
| LOT_ID | 批次編號 |
| VENDOR_LOT | 外包廠批次 |
| CUSTOM_LOT | 客戶批次 |
| PROCESS | 製程名稱 |
有時候工程師需要設計邏輯:
如果資料來自某個製程,就顯示客戶批次
否則顯示外包批次
這時就會用到 CASE。
例如:
SELECT
CASE
WHEN process_stage = 'FINAL_TEST'
AND supplier = 'ABC'
THEN custom_lot
ELSE vendor_lot
END AS LotNumber
FROM production_data
邏輯意思是:
| 條件 | LotNumber |
|---|---|
| FINAL_TEST + ABC | custom_lot |
| 其他 | vendor_lot |
很多工程師會犯的一個錯誤
例如寫成:
CASE
WHEN vendor_lot = custom_lot THEN fab_lot
WHEN process_stage = 'FINAL_TEST'
AND supplier = 'ABC'
THEN custom_lot
ELSE vendor_lot
END
乍看之下沒有問題,但其實可能出現錯誤結果。
原因是:
第一個條件會優先被判斷。
如果 vendor_lot = custom_lot
那後面的條件永遠不會執行。
這就是很多資料錯誤的來源。
正確的設計方式
如果我們真正的需求是:
只有在 FINAL_TEST 且供應商是 ABC 時使用 custom_lot
那 CASE 應該寫成:
CASE
WHEN process_stage = 'FINAL_TEST'
AND supplier = 'ABC'
THEN custom_lot
ELSE vendor_lot
END
這樣邏輯會更清楚。
SQL 動態條件的另一個常見問題
在很多系統中,SQL 會用程式組合,例如:
WHERE product IN (...)
AND stage IN (...)
AND test_group IN (...)
如果是程式動態產生,很容易寫成:
query = "SELECT * FROM table WHERE product IN ('{}')".format(product_list)
如果 product_list 是:
A,B,C
最後 SQL 會變成:
IN ('A,B,C')
這其實只是一個字串,不是三個條件。
正確應該是:
IN ('A','B','C')
因此在正式系統中,工程師通常會使用:
- 參數化 SQL
- ORM
- Prepared Statement
避免錯誤與安全問題。
SQL JOIN 也可能造成資料變化
很多查詢會使用 JOIN,例如:
SELECT *
FROM order_table o
LEFT JOIN shipment_table s
ON o.order_id = s.order_id
LEFT JOIN 的意思是:
左邊資料一定保留
右邊沒有資料時會變成 NULL
因此如果 CASE 使用右邊欄位:
s.shipment_code
結果可能會是:
NULL
這也是查詢結果「看起來怪怪的」常見原因。
SQL CASE WHEN 設計最佳實務
實務上工程師通常會遵守以下原則:
1️⃣ 條件最特殊的放最前面
因為 CASE 是由上往下判斷。
2️⃣ 不要加入無關條件
多餘條件會讓邏輯變複雜。
3️⃣ CASE 只做一件事
不要讓一個 CASE 同時處理太多邏輯。
4️⃣ SQL 條件盡量可讀
比起:
CASE WHEN A AND B OR C
更好的寫法是:
CASE
WHEN (A AND B) OR C
一個簡單的心法
工程師通常會用這個方式檢查 SQL:
把 CASE 想成 if-else
例如:
if 條件1:
回傳A
elif 條件2:
回傳B
else:
回傳C
如果寫成 SQL:
CASE
WHEN 條件1 THEN A
WHEN 條件2 THEN B
ELSE C
END
結論
當 SQL 查詢結果不正確時,不一定是語法錯誤。
最常見原因其實是:
- CASE 條件順序錯誤
- 條件設計不清楚
- JOIN 導致 NULL
- 動態 SQL 組錯
理解 CASE WHEN 的判斷順序,可以解決大部分 SQL 查詢邏輯問題。
留言
張貼留言