🧾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 查詢邏輯問題。

留言

這個網誌中的熱門文章

🔍Vue.js 專案錯誤排查:解決 numericFields is not defined 與合併儲存格邏輯最佳化

🖥️遠端桌面連線完整新手指南:Windows RDP、Chrome Remote Desktop、AnyDesk、TeamViewer 一次搞懂

🔎EF Core 連 Oracle 出現 ORA-00600 [kpp_concatq:2] 的完整排錯指南(含 EF Core ToString/CultureInfo 錯誤)