Logo

新人日誌

首頁關於我部落格

新人日誌

Logo

網站會不定期發佈技術筆記、職場心得相關的內容,歡迎關注本站!

網站
首頁關於我部落格
部落格
分類系列文

© 新人日誌. All rights reserved. 2020-present.

本文為「SQL 資料庫新手村」系列第 41 篇

SQL SELECT 入門:用 CASE WHEN 做條件判斷

最後更新:2026年1月29日資料庫

有時候資料庫裡沒有你需要的欄位,但可以從現有的欄位算出來。

比如說,老闆問你:「幫我把 20-30 歲、30-40 歲、40-50 歲、50 歲以上的會員,分別算出他們的平均消費金額。」

你心想:這不就是 GROUP BY 嗎?按照年齡區間分組就好了,小菜一碟。

但仔細一看,會員表裡面只有「年齡」欄位,沒有「年齡區間」欄位:

會員年齡
Alice25
Bob35
Carol42
David55
年齡25
年齡35
年齡42
年齡55

為什麼沒有?

根據第三正規化原則,如果一個欄位的值可以從其他欄位計算出來,就不需要額外儲存。

年齡區間可以從年齡算出來,所以資料庫裡不會有「年齡區間」這個欄位。

所以你必須自己產生「年齡區間」這個欄位。

條件判斷是什麼?

怎麼產生「年齡區間」這個欄位呢?

你需要根據「年齡」欄位的值,判斷它落在哪個區間,然後產生對應的結果:

  • 如果年齡是 25,就產生 ’20-30′
  • 如果年齡是 35,就產生 ’30-40′
  • 如果年齡是 42,就產生 ’40-50′
  • 如果年齡是 55,就產生 ’50以上’

這種「根據條件產生不同結果」的邏輯,就是條件判斷。

在其他程式語言裡,條件判斷通常用 switch 或 match 來寫。

JavaScript 的 switch:

switch (性別) {
    case 'M':
        return '先生';
    case 'F':
        return '女士';
    default:
        return '朋友';
}

Python 的 match:

match 性別:
    case 'M':
        return '先生'
    case 'F':
        return '女士'
    case _:
        return '朋友'

在 SQL 裡面,條件判斷用 CASE WHEN 來寫,邏輯是類似的。

CASE WHEN 的基本語法

前面提到,JavaScript 用大括號 {} 來標示程式碼區塊的範圍,Python 用縮排加上冒號來區分。

但在 SQL 裡面,很少使用括號。圓括號 () 是用來把資料放在一起,方括號和大括號幾乎不使用。

那 SQL 怎麼知道條件判斷從哪裡開始、到哪裡結束呢?

答案是:用保留字。

SQL 用 CASE 表示條件判斷開始,用 END 表示條件判斷結束:

CASE
    WHEN 條件1 THEN 值1
    WHEN 條件2 THEN 值2
    WHEN 條件3 THEN 值3
    ELSE 預設值
END

中間的 WHEN 和 THEN 也是保留字:

  • WHEN:當什麼條件成立
  • THEN:就返回什麼值

最後的 ELSE 是前面條件都不成立時的預設值。

整理一下:

保留字意思
CASE條件判斷開始
WHEN當條件成立
THEN就返回這個值
ELSE前面都不成立時的預設值
END條件判斷結束
意思條件判斷開始
意思當條件成立
意思就返回這個值
意思前面都不成立時的預設值
意思條件判斷結束

要注意的是,當某個 WHEN 條件成立時,會直接返回值,後面的條件不會再判斷。

這就像 JavaScript 裡 return 之後就不會繼續執行一樣。

舉例來說:

CASE
    WHEN 年齡 >= 20 THEN '20歲以上'
    WHEN 年齡 >= 30 THEN '30歲以上'
    ELSE '20歲以下'
END

如果年齡是 35,第一個條件 年齡 >= 20 就成立了,會直接返回 ’20歲以上’,不會再判斷第二個條件。

所以條件的順序很重要。如果你想要正確區分年齡區間,應該把範圍小的條件放前面,或是用更精確的條件:

CASE
    WHEN 年齡 >= 30 THEN '30歲以上'
    WHEN 年齡 >= 20 THEN '20-30歲'
    ELSE '20歲以下'
END

CASE WHEN 和 GROUP BY 的差別

你可能會想:GROUP BY 不是也可以把資料分組嗎?

但 CASE WHEN 和 GROUP BY 做的事情不一樣:

GROUP BY:把多筆資料壓縮成一筆,原本的資料列會減少。

CASE WHEN:根據條件產生一個新的欄位,原本的資料列數量不變,每一筆資料都還在。

以這個例子來說:

會員年齡
Alice25
Bob35
Carol42
David55
年齡25
年齡35
年齡42
年齡55

用 CASE WHEN

用 CASE WHEN 產生年齡區間後:

會員年齡年齡區間
Alice2520-30
Bob3530-40
Carol4240-50
David5550以上
年齡25
年齡區間20-30
年齡35
年齡區間30-40
年齡42
年齡區間40-50
年齡55
年齡區間50以上

資料還是 4 筆,只是多了一個「年齡區間」欄位。

這個欄位是暫時計算出來的,原本的「年齡」欄位還在,不會被壓縮或消失。

用 GROUP BY

如果用 GROUP BY 年齡呢?

年齡
25
35
42
55

GROUP BY 會把「年齡相同的」資料壓縮在一起。但這 4 筆資料的年齡都不同,所以還是 4 筆。

而且 GROUP BY 沒辦法幫你產生「年齡區間」這個新欄位,它只能用現有的欄位來分組。

範例:產生年齡區間欄位

老闆說:「幫我把 20-30 歲、30-40 歲、40-50 歲、50 歲以上的會員,分別算出他們的平均消費金額。」

這個問題需要分兩步。

為什麼?

因為我們要按照「年齡區間」分組,但資料庫裡沒有這個欄位。

所以要先用 CASE WHEN 產生「年齡區間」欄位。

CASE WHEN 通常會搭配 SELECT 使用,把計算出來的結果當作一個新欄位輸出。

而 SELECT 輸出的內容,可以當作一張新的表單(臨時表單),作為另一個查詢的輸入。

所以我們可以:

  1. 第一步:用 SELECT + CASE WHEN 產生「年齡區間」欄位,得到一張臨時表單
  2. 第二步:從這張臨時表單,用 GROUP BY 按照年齡區間分組,搭配 AVG 計算平均消費金額

第一步:產生年齡區間欄位

首先,寫出 CASE WHEN 條件判斷:

CASE
    WHEN 年齡 >= 20 AND 年齡 < 30 THEN '20-30'
    WHEN 年齡 >= 30 AND 年齡 < 40 THEN '30-40'
    WHEN 年齡 >= 40 AND 年齡 < 50 THEN '40-50'
    WHEN 年齡 >= 50 THEN '50以上'
    ELSE '20以下'
END AS 年齡區間

這段條件判斷的邏輯是:

  • 如果年齡在 20-30 之間,返回 ’20-30′
  • 如果年齡在 30-40 之間,返回 ’30-40′
  • 如果年齡在 40-50 之間,返回 ’40-50′
  • 如果年齡 50 以上,返回 ’50以上’
  • 其他情況(20 歲以下),返回 ’20以下’

最後用 AS 年齡區間 給這個新欄位取名字。

接著,把這段 CASE WHEN 放進 SELECT 裡面。

因為我們要把計算出來的「年齡區間」輸出成一個新欄位,這樣才能產生一張新的表單,讓第二步可以繼續使用。

SELECT 
    會員,
    金額,
    【CASE WHEN 條件判斷】
FROM 會員訂單表

組合起來:

SELECT 
    會員,
    金額,
    CASE
        WHEN 年齡 >= 20 AND 年齡 < 30 THEN '20-30'
        WHEN 年齡 >= 30 AND 年齡 < 40 THEN '30-40'
        WHEN 年齡 >= 40 AND 年齡 < 50 THEN '40-50'
        WHEN 年齡 >= 50 THEN '50以上'
        ELSE '20以下'
    END AS 年齡區間
FROM 會員訂單表

執行結果:

原本的表單:

會員金額年齡
Alice5000025
Bob12000035
Carol3000042
………
金額50000
年齡25
金額120000
年齡35
金額30000
年齡42
金額…
年齡…

執行後會得到:

會員金額年齡區間
Alice5000020-30
Bob12000030-40
Carol3000040-50
………
金額50000
年齡區間20-30
金額120000
年齡區間30-40
金額30000
年齡區間40-50
金額…
年齡區間…

這裡我們只 SELECT 需要的欄位(會員、金額、年齡區間),所以輸出不會有年齡欄位。

這樣就產生了一個原本不存在的「年齡區間」欄位。

第二步:按照年齡區間分組

第一步的結果是一張臨時表單,包含「會員」、「金額」、「年齡區間」三個欄位。

我們要從這張臨時表單,按照年齡區間分組,計算平均消費金額。

首先,把第一步的查詢當作資料來源,放在 FROM 後面:

SELECT ...
FROM (第一步的查詢) AS 會員年齡區間表

這裡要用 AS 會員年齡區間表 給這張臨時表單取個名字。

接著,加上 GROUP BY 和 AVG:

SELECT 年齡區間, AVG(金額) AS 平均消費金額
FROM (第一步的查詢) AS 會員年齡區間表
GROUP BY 年齡區間

組合起來:

SELECT 年齡區間, AVG(金額) AS 平均消費金額
FROM (
    SELECT 
        會員,
        金額,
        CASE
            WHEN 年齡 >= 20 AND 年齡 < 30 THEN '20-30'
            WHEN 年齡 >= 30 AND 年齡 < 40 THEN '30-40'
            WHEN 年齡 >= 40 AND 年齡 < 50 THEN '40-50'
            WHEN 年齡 >= 50 THEN '50以上'
            ELSE '20以下'
        END AS 年齡區間
    FROM 會員訂單表
) AS 會員年齡區間表
GROUP BY 年齡區間

執行結果:

第一步的結果(作為輸入):

會員金額年齡區間
Alice5000020-30
Bob12000030-40
Carol3000040-50
………
金額50000
年齡區間20-30
金額120000
年齡區間30-40
金額30000
年齡區間40-50
金額…
年齡區間…

執行後會得到:

年齡區間平均消費金額
20-3045000
30-4085000
40-5062000
50以上78000
平均消費金額45000
平均消費金額85000
平均消費金額62000
平均消費金額78000

這樣就完成了老闆的需求。

CASE WHEN 的簡化寫法

如果條件是判斷某個欄位「等於」某個值,可以用簡化寫法:

CASE 欄位
    WHEN 值1 THEN 結果1
    WHEN 值2 THEN 結果2
    ELSE 預設值
END

這個寫法更像其他程式語言的 switch-case。

範例:根據性別產生稱呼

假設要寫信給會員,需要根據性別來決定稱呼。

SELECT 
    會員,
    CASE 性別
        WHEN 'M' THEN '先生'
        WHEN 'F' THEN '女士'
        ELSE '朋友'
    END AS 稱呼
FROM 會員表

這段 SQL 的邏輯是:

  • 如果性別是 ‘M’(男),稱呼是「先生」
  • 如果性別是 ‘F’(女),稱呼是「女士」
  • 其他情況(性別是 NULL 或其他值),稱呼是「朋友」

執行後會得到:

會員稱呼
Alice女士
Bob先生
Carol女士
David朋友
稱呼女士
稱呼先生
稱呼女士
稱呼朋友

CASE WHEN 可以放在哪裡?

CASE WHEN 最常放在 SELECT 裡面,用來產生新的欄位。

但它也可以放在其他地方,例如:

放在 WHERE 裡面:

SELECT *
FROM 訂單
WHERE CASE
    WHEN 會員等級 = 'VIP' THEN 金額 > 10000
    ELSE 金額 > 50000
END

放在 ORDER BY 裡面:

SELECT *
FROM 會員
ORDER BY CASE 性別
    WHEN 'F' THEN 1
    WHEN 'M' THEN 2
    ELSE 3
END

不過最常見的用法還是放在 SELECT 裡面產生新欄位。

小結

這篇文章介紹了 CASE WHEN 條件判斷:

  1. 為什麼需要條件判斷:有時候資料庫裡沒有你需要的欄位,需要透過條件判斷來產生
  2. 基本語法:CASE WHEN 條件 THEN 值 ELSE 預設值 END
  3. 簡化寫法:當條件是判斷欄位等於某個值時,可以用 CASE 欄位 WHEN 值 THEN 結果 的寫法
  4. 搭配 GROUP BY:可以先用 CASE WHEN 產生新欄位,再按照這個欄位分組
上一篇SQL SELECT 入門:用 HAVING 篩選分組後的結果
下一篇SQL SELECT 入門:用 COALESCE 函數處理空值

留言 (2)

林紗奈
林紗奈2026年1月28日

感謝大大,大概看懂了

徐培鈞
徐培鈞2026年1月29日

謝謝支持🙏

發表留言

留言將在審核後顯示。

資料庫

目錄

  • 條件判斷是什麼?
  • CASE WHEN 的基本語法
  • CASE WHEN 和 GROUP BY 的差別
  • 用 CASE WHEN
  • 用 GROUP BY
  • 範例:產生年齡區間欄位
  • 第一步:產生年齡區間欄位
  • 第二步:按照年齡區間分組
  • CASE WHEN 的簡化寫法
  • 範例:根據性別產生稱呼
  • CASE WHEN 可以放在哪裡?
  • 小結