1. 程式人生 > >Mysql查詢時case when語句的使用

Mysql查詢時case when語句的使用

前言

前幾天在技術論壇論壇上發現一個求助帖,大體意思就是要把一個表中的資料按條件分成兩類,每一類排序方式不同,然後整體作為查詢的結果集,乍一看這問題不是很難,很多人給出的答案是分別查詢排序後再 union合併到一起,但是後來樓主明確指出不想使用 union 操作,這時有一位高人巧用 case when 語句解決了問題,其實這是我第一次接觸 case when 語句,於是查詢了一下具體用法,在此做個小結,方便日後查詢使用。

建立示例表格

資料庫表格結構很簡單,馬上要期末了,就以學習成績為資料來建立一張資料表,表中包含唯一ID、學號、姓名、性別、分數等列,其中性別這一列用整數代表,0表示男,1表示女,建立表格的sql語句如下:

CREATE TABLE `grade` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `number` int(4) NOT NULL DEFAULT '0',
  `name` varbinary(32) NOT NULL DEFAULT '',
  `sex` int(4) NOT NULL DEFAULT '0',
  `score` int(4) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `find_index` (`number`,`name`)
) ENGINE=InnoDB DEFAULT
CHARSET=binary ROW_FORMAT=DYNAMIC;

插入測試資料

表格建立完成可以使用視覺化工具或者insert語句插入測試資料,插入測試資料後查詢結果如下:

mysql> select number,name,sex,score from grade;
+----------+----------+-----+-------+
| number   | name     | sex | score |
+----------+----------+-----+-------+
| 20180001 | xiaoming |   0 |    68 |
| 20180002 | xiaohong |   1 |    98 |
| 20180003 | xiaobing |   0 |    78 |
| 20180004 | xiaoli   |   0 |    88 |
| 20180005 | zhangsan |   0 |    32 |
| 20180006 | zhaosi   |   0 |    58 |
| 20180007 | marry    |   1 |    78 |
| 20180008 | tom      |   0 |   100 |
| 20180009 | feifei   |   1 |    90 |
| 20180010 | lili     |   1 |    92 |
| 20180011 | xiaozhao |   0 |    52 |
| 20180012 | xiaowang |   0 |    62 |
+----------+----------+-----+-------+
12 rows in set (0.00 sec)

獲取平均成績

班主任們坐在一起做喜歡做的事就是比一下自己的學生和別人班的差距,誰讓他們每個人帶的學生都是一屆不如一屆呢!(你們是我帶過的學生中最差的一屆!!!)說到比成績一般都是比較並均分,sql語句可能會寫成下面這樣:

mysql> select avg(score) as 平均分 from grade;
+-----------+
| 平均分    |
+-----------+
|   74.6667 |
+-----------+
1 row in set (0.02 sec)

是的,很簡單就能獲得班級的平均分,如果要分組呢?比如分別查一下男生和女生的平均分,因為我們知道表中的sex表示性別,所以直接按照sex分組就可以實現,可以將語句簡單寫成這樣:

mysql> select sex as 性別, avg(score) as 平均分 from grade group by sex;
+--------+-----------+
| 性別   | 平均分    |
+--------+-----------+
|      0 |   67.2500 |
|      1 |   89.5000 |
+--------+-----------+
2 rows in set (0.00 sec)

是不是很簡單?可是性別顯示成0和1確實不利於閱讀,但是表中又沒有儲存0、1與男、女的對應關係,應該怎麼辦呢?這就要用到我們今天所要用到的case when語句了,語法上共有兩種寫法,看著具體例子體會一下吧。

case when 語句的使用

  1. 第一種用法:case後面跟列名,when後面跟對應值

    CASE case_value
     WHEN when_value THEN statement_list
     [WHEN when_value THEN statement_list] ...
     [ELSE statement_list]
    END

    這種用法正好解決我們剛剛提出的問題,當sex值為0時當前列顯示“男”,否則顯示“女”,sql寫法如下:

    mysql> select (case sex when 0 then '男' else '女' end) as 性別, avg(score) as 平均分
     -> from grade group by sex;
    +--------+-----------+
    | 性別   | 平均分    |
    +--------+-----------+
    | 男     |   67.2500 |
    | 女     |   89.5000 |
    +--------+-----------+
    2 rows in set (0.00 sec)
  2. 第二種用法:case後面空白,when後面跟著判斷條件

    CASE
     WHEN search_condition THEN statement_list
     [WHEN search_condition THEN statement_list] ...
     [ELSE statement_list]
    END

    針對於這種寫法,我們考慮這樣一種需求,學生成績是有評分的,大於等於90分的學生是A,小於90分大於等於60分的學生是B, 其餘的學生是C,現在要查詢評分為A、B、C的學生成績的平均分分別是多少,因為成績評分並不是單獨的一列,所以不能簡單的 使用 group by 來分組實現了,但是可以利用 case when 語句實現,寫起來也很簡單,看看下面的sql語句就知道了!

    mysql> select (case when score >= 90 then 'A' when score < 60 then 'C' else 'B' end) as 等級,
     -> avg(score) as 平均分 from grade group by 等級;
    +--------+-----------+
    | 等級   | 平均分    |
    +--------+-----------+
    | A      |   95.0000 |
    | B      |   74.8000 |
    | C      |   47.3333 |
    +--------+-----------+
    3 rows in set (0.00 sec)

總結

  1. case when 語句共有兩種寫法,使用時要區別兩種用法的差異。
  2. 使用 case when 語句可以實現修改數值的對應關係,還可以按照複雜的條件進行分組。
  3. 關於 case when 語句的詳細用法,有興趣的同學可以參考一下官方文件:13.6.5.1 CASE Syntax