CASE 表達式是 T-SQL 中實現條件邏輯的核心工具,可在 SELECT、WHERE、ORDER BY、SET 等子句中使用。本文透過實例示範簡單與搜尋兩種 CASE 形式,並說明資料型別優先順序與常見陷阱。
比較單一運算式與一組 WHEN 值是否相等。
CASE 輸入運算式
WHEN 比較值1 THEN 結果1
WHEN 比較值2 THEN 結果2
...
ELSE 預設結果
END
評估一組獨立的布林運算式,彈性較高。
CASE
WHEN 布林運算式1 THEN 結果1
WHEN 布林運算式2 THEN 結果2
...
ELSE 預設結果
END
USE TSQLFundamentals2008;
GO
SELECT
productid,
productname,
categoryid,
CASE categoryid
WHEN 1 THEN N'飲料'
WHEN 2 THEN N'調味品'
WHEN 3 THEN N'乳製品'
WHEN 4 THEN N'糖果點心'
WHEN 5 THEN N'穀類麥片'
WHEN 6 THEN N'肉禽類'
WHEN 7 THEN N'農產品'
WHEN 8 THEN N'海產品'
ELSE N'未知分類'
END AS categoryname
FROM Production.Products;
| productid | productname | categoryid | categoryname |
|---|---|---|---|
| 1 | Chai | 1 | 飲料 |
| 2 | Chang | 1 | 飲料 |
| 3 | Aniseed Syrup | 2 | 調味品 |
| 4 | Chef Anton's Cajun Seasoning | 2 | 調味品 |
| 5 | Chef Anton's Gumbo Mix | 2 | 調味品 |
| ... | ... | ... | ... |
DECLARE @SortBy VARCHAR(20) = 'PriceDesc';
SELECT *
FROM Products
ORDER BY
CASE @SortBy
WHEN 'PriceAsc' THEN unitprice
WHEN 'PriceDesc' THEN -unitprice -- 數值型別可用負號反轉
WHEN 'NameAsc' THEN productname
ELSE productid
END;
SELECT
categoryid,
COUNT(*) AS 總筆數,
SUM(CASE WHEN unitprice > 50 THEN 1 ELSE 0 END) AS 高價商品數,
SUM(CASE WHEN discontinued = 1 THEN 1 ELSE 0 END) AS 已停售數
FROM Products
GROUP BY categoryid;
UPDATE Customers
SET region = CASE
WHEN region IN ('WA', 'Wash.', 'Washington') THEN 'WA'
WHEN region IN ('CA', 'Calif.', 'California') THEN 'CA'
ELSE region
END;
SELECT
orderid,
CASE
WHEN qty = 0 THEN 0
ELSE totalamount / qty
END AS 單價
FROM OrderDetails;
CASE 所有 THEN/ELSE 回傳值必須可隱含轉換為同一資料型別,遵循資料型別優先順序(高優先順序勝出)。常見錯誤:
-- 錯誤:混合字串與數值 CASE WHEN col = 1 THEN '一' ELSE 2 END -- 2 會被轉為 '2',但若 ELSE 是日期則會轉換失敗 -- 正確:統一為字串 CASE WHEN col = 1 THEN '一' ELSE '二' END
ELSE 子句(預設回傳 NULL 易導致下游邏輯錯誤)。WHEN 子句順序即評估順序,將高頻率命中條件前置可微幅提升效能。CASE 層級過深(> 10)考慮重構為查詢表或函數。CASE 表達式是 T-SQL 中最靈活的條件邏輯工具,善用它能將商業規則直接表達在查詢中,減少應用層往返,提升可維護性與效能。