case 表達式的基本用法
case when sex=1 then "男"
when sex=2 then "女"
else '其他' end
或者
case sex when 1 then "男"
when 2 then "女"
else '其他' end
注意事項
- 每個條件具有排他性,執行到符合條件的分支就不會繼續執行下去。
- then後面返回的數據類型要一致。
- 不寫else,執行不到符合條件的分支返回null。
使用示例:
根據條件聚合數據
mysql> select * from poptbl;
+-----------+------------+
| pref_name | population |
+-----------+------------+
| 東京 | 400 |
| 佐賀 | 100 |
| 德島 | 100 |
| 愛媛 | 150 |
| 福岡 | 300 |
| 羣馬 | 50 |
| 長崎 | 200 |
| 香川 | 200 |
| 高知 | 200 |
+-----------+------------+
統計各個區域的人數
SELECT
(
CASE
WHEN pref_name IN ( "德島", "香川", "愛媛", "高知" ) THEN
"四國"
WHEN pref_name IN ( "福岡", "佐賀", "長崎" ) THEN
"九州" ELSE "其他"
END
),
sum( population )
FROM
poptbl
GROUP BY
(
CASE
WHEN pref_name IN ( "德島", "香川", "愛媛", "高知" ) THEN
"四國"
WHEN pref_name IN ( "福岡", "佐賀", "長崎" ) THEN
"九州" ELSE "其他"
END
);
結果:
+------+------+
| 區域 | 人數 |
+------+------+
| 九州 | 600 |
| 其他 | 450 |
| 四國 | 650 |
+------+------+
一條語句根據不同條件聚合數據,可以得到不同條件的多列數據
mysql> select * from poptbl2;
+-----------+-----+------------+
| pref_name | sex | population |
+-----------+-----+------------+
| 東京 | 1 | 250 |
| 東京 | 2 | 150 |
| 佐賀 | 1 | 20 |
| 佐賀 | 2 | 80 |
| 德島 | 1 | 60 |
| 德島 | 2 | 40 |
| 愛媛 | 1 | 100 |
| 愛媛 | 2 | 50 |
| 福岡 | 1 | 100 |
| 福岡 | 2 | 200 |
| 長崎 | 1 | 125 |
| 長崎 | 2 | 125 |
| 香川 | 1 | 100 |
| 香川 | 2 | 100 |
| 高知 | 1 | 100 |
| 高知 | 2 | 100 |
+-----------+-----+------------+
統計不同性別人數
SELECT
pref_name AS 地區,
sum( CASE WHEN sex = 1 THEN population ELSE 0 END ) AS 男,
sum( CASE WHEN sex = 2 THEN population ELSE 0 END ) AS 女
FROM
poptbl2
GROUP BY
pref_name;
結果
+------+------+------+
| 地區 | 男 | 女 |
+------+------+------+
| 東京 | 250 | 150 |
| 佐賀 | 20 | 80 |
| 德島 | 60 | 40 |
| 愛媛 | 100 | 50 |
| 福岡 | 100 | 200 |
| 長崎 | 125 | 125 |
| 香川 | 100 | 100 |
| 高知 | 100 | 100 |
+------+------+------+
根據條件進行不同的數據更新
mysql> select * from salaries;
+------+--------+
| name | salary |
+------+--------+
| 木村 | 220000 |
| 相田 | 300000 |
| 神崎 | 270000 |
| 齊藤 | 290000 |
+------+--------+
條件:
- 對當前工資爲 30 萬日元以上的員工,降薪 10%。
- 對當前工資爲 25 萬日元以上且不滿 28 萬日元的員工,加薪 20%。
執行
UPDATE salaries SET salary = ( CASE WHEN salary > 300000 THEN
salary * 0.9
WHEN salary > 250000
AND salary < 280000 THEN
salary * 1.2 ELSE salary
END );
結果
mysql> select * from salaries;
+------+--------+
| name | salary |
+------+--------+
| 木村 | 220000 |
| 相田 | 300000 |
| 神崎 | 324000 |
| 齊藤 | 290000 |
+------+--------+
表聚合
mysql> select * from coursemaster;
+-----------+-------------+
| course_id | course_name |
+-----------+-------------+
| 1 | 會計入門 |
| 2 | 財務知識 |
| 3 | 簿記考試 |
| 4 | 稅務師 |
+-----------+-------------+
4 rows in set (0.00 sec)
mysql> select * from opencourses;
+--------+-----------+
| month | course_id |
+--------+-----------+
| 200706 | 1 |
| 200706 | 3 |
| 200706 | 4 |
| 200707 | 4 |
| 200708 | 2 |
| 200708 | 4 |
+--------+-----------+
SELECT
course_name,
( CASE WHEN course_id IN ( SELECT course_id FROM opencourses WHERE MONTH = "200706" ) THEN 1 ELSE 0 END ) AS "6月",
( CASE WHEN course_id IN ( SELECT course_id FROM opencourses WHERE MONTH = "200707" ) THEN 1 ELSE 0 END ) AS "7月",
( CASE WHEN course_id IN ( SELECT course_id FROM opencourses WHERE MONTH = "200708" ) THEN 1 ELSE 0 END ) AS "8月"
FROM
coursemaster;
SELECT
course_name,
CASE
WHEN FIND_IN_SET( "200706", GROUP_CONCAT( MONTH ) ) THEN
TRUE ELSE FALSE
END AS "6月",
CASE
WHEN FIND_IN_SET( "200707", GROUP_CONCAT( MONTH ) ) THEN
TRUE ELSE FALSE
END AS "7月",
CASE
WHEN FIND_IN_SET( "200708", GROUP_CONCAT( MONTH ) ) THEN
TRUE ELSE FALSE
END AS "8月"
FROM
coursemaster AS cm
INNER JOIN opencourses AS oc ON oc.course_id = cm.course_id
GROUP BY
course_name;
結果
+-------------+-----+-----+-----+
| course_name | 6月 | 7月 | 8月 |
+-------------+-----+-----+-----+
| 會計入門 | 1 | 0 | 0 |
| 稅務師 | 1 | 1 | 1 |
| 簿記考試 | 1 | 0 | 0 |
| 財務知識 | 0 | 0 | 1 |
+-------------+-----+-----+-----+
個人覺着這個 case when 其實就是根據條件做一次邏輯計算,替換指定的字段。按照這個想法去寫 sql 即可。