Mysql 中 Case 的使用介紹
- 2019 年 12 月 22 日
- 筆記
工作中經常需要寫各種 sql 來統計線上的各種業務數據,使用 CASE 能讓你的統計事半功倍,如果能用好它,不僅SQL 能解決的問題更廣泛,寫法也會漂亮地多,接下來讓我們看看 CASE 的各種妙用吧,在開始之前我們簡單學習一下 CASE 表達式的寫法
CASE 表達式的兩種寫法
CASE 表示式有簡單表達式和搜索表達式兩種,如下
-- 簡單 CASE 表達式 CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END -- 搜索 CASE 表達式 CASE WHEN sex = '1' THEN '男' WHEN sex = '2' THEN '女' ELSE '其他' END
需要注意的是每個WHEN
子句都具有排他性,也就是說如果執行到某個 WHEN
子句為真,則剩餘的 WHEN
子句不會執行,所以為了引起不必要的麻煩,WHEN 子句要注意條件的互斥性
CASE 的用法詳解
知道了 CASE 的用法,接下來我們來舉幾個例子來看下 CASE 的幾種妙用,首先讓我們準備兩張表(欄位設計還有優化的空間,只是為了方便演示 CASE 的使用),用戶表(customer
) 和 訂單表(order
),一個用戶可以有多個訂單,所以用戶與訂單的關係是一對多的

這兩個表的數據如下
customer 表
id |
name |
gender |
district |
vip_level |
---|---|---|---|---|
1 |
張三 |
女 |
杭州 |
1 |
2 |
李四 |
男 |
杭州 |
2 |
3 |
王五 |
男 |
海口 |
3 |
4 |
趙六 |
男 |
義烏 |
2 |
5 |
王五 |
男 |
三沙 |
2 |
order 表
id |
customer_id |
---|---|
1 |
1 |
2 |
1 |
3 |
2 |
4 |
3 |
5 |
4 |
數據準備好了,現在重點來了,考慮以下問題,我們該怎麼處理
1.統計浙江,海南的用戶數普通寫法: 寫兩個 sql 分別統計浙江,海南的訂單數
-- 統計浙江用戶數 SELECT COUNT(*) FROM customer WHERE district IN ('杭州','義烏') -- 統計海南用戶數 SELECT COUNT(*) FROM customer WHERE district IN ('海口', '三沙')
進階用法:使用 CASE 來統計,一句 sql 搞定
SELECT CASE district when '義烏' then '浙江' when '杭州' then '浙江' when '海口' then '海南' when '三沙' then '海南' ELSE '其他' END AS 'province', COUNT(*) FROM customer GROUP BY province
2.將 vip_ level 為 3 的更新成 2 ,將vip_level 為 2 的更新成 3如果說統計 「統計浙江,海南的用戶數」可以用兩個 sql 分別來統計的話,那這個更新 vip_level 的操作就必須要用CASE 來更新了,假設我們用上個例子的套路分別寫兩個 sql 來更新的話,看下會發生什麼
-- 先將vip_level 為 3 的更新為 2 UPDATE customer SET vip_level=2 WHERE vip_level=3 -- 再將vip_level 為 2 的更新為 3 UPDATE customer SET vip_level=3 WHERE vip_level=2
以上兩步確實將 vip_level 為 2 的更新為 3了,但 vip_level 為 3 的經過上面兩步之後最終並沒有變成 2(先變成 2 再變成 3),那我們看看如何用 CASE 來實現我們的需求
UPDATE customer SET vip_level CASE WHEN vip_level = 3 THEN 2 WHEN vip_level = 2 THEN 3 ELSE vip_level END
可以看到實現方式簡潔明了,需要注意的是最後一步 「ELSE vip END」極為關鍵,如果不加這一句,則如果 vip_level 不為 2 或 3,會被更新成 NULL,這樣就會把其他值的 vip_level 給清掉
總結
可以看到,使用 CASE 給我們帶來了很大的便利,不僅邏輯上更為緊湊,而且相比於多條 sql 的執行,使用 「CASE WHEN」一行就能解決問題,方便了很多