Mysql之case基本用法
MySQL 的 case when 的語法有兩種:
1.簡單函式 (比較col_name和when後面的值是否相等)
CASE [col_name] WHEN [value1] THEN [result1]…ELSE [default] END
2.搜尋函式 (判斷when後面的表示式expr是否為true,如果為true,則返回result1)
CASE WHEN [expr] THEN [result1]…ELSE [default] END
兩種語法的區別
簡單函式
CASE [col_name] WHEN [value1] THEN [result1]…ELSE [default] END: 列舉這個欄位所有可能的值
SELECT
NAME '樹名',
CASE NAME
WHEN '桃樹' THEN
'桃花'
WHEN '梨樹' THEN
'梨花'
WHEN '芙蓉' THEN
'蓮花'
ELSE
'無名花'
END '花名'
FROM
tree_info;
查詢結果:
搜尋函式
CASE WHEN [expr] THEN [result1]…ELSE [default] END
:搜尋函式可以寫判斷,並且搜尋函式只會返回第一個符合條件的值,其他case
SELECT age '年齡段', CASE WHEN age <= 10 THEN '不愁' WHEN age <= 20 THEN '不悔' WHEN age <= 30 THEN '而立' WHEN age <= 40 THEN '不惑' WHEN age <= 50 THEN '知天命' WHEN age <= 60 THEN '耳順' ELSE '年級大了' END '狀態' FROM age_info;
查詢結果:
特殊用法
1.聚合函式 sum 配合 case when 的簡單函式實現行轉列
表1:courses
表2:score
表3:student:
測試:
SELECT
st.stu_id '學號',
st.stu_name '姓名',
SUM(
CASE co.course_name
WHEN '語文' THEN
sc.scores
ELSE
0
END
) '語文',
SUM(
CASE co.course_name
WHEN '數學' THEN
sc.scores
ELSE
0
END
) '數學',
SUM(
CASE co.course_name
WHEN '物理' THEN
sc.scores
ELSE
0
END
) '物理',
SUM(
CASE co.course_name
WHEN '化學' THEN
sc.scores
ELSE
0
END
) '化學',
SUM(
CASE co.course_name
WHEN '生物' THEN
sc.scores
ELSE
0
END
) '生物',
SUM(
CASE co.course_name
WHEN '歷史' THEN
sc.scores
ELSE
0
END
) '歷史'
FROM
student st
LEFT JOIN score sc ON st.stu_id = sc.stu_id
LEFT JOIN courses co ON co.course_no = sc.course_no
GROUP BY
st.stu_id
ORDER BY
NULL;
測試結果:
一般我們查詢的時候,根據stu_id分組,例如:
SELECT
st.stu_id '學號',
st.stu_name '姓名',
GROUP_CONCAT(sc.scores),GROUP_CONCAT(sc.`course_no`),GROUP_CONCAT(co.`course_name`)
FROM
student st
LEFT JOIN score sc ON st.stu_id = sc.stu_id
LEFT JOIN courses co ON co.course_no = sc.course_no
GROUP BY
st.stu_id
ORDER BY
NULL;
查詢結果:
這樣的查詢結果並不如例如case when 的行轉列資料清晰
2.把一行拆分為多了的示例
SELECT SipAccount, COUNT(1) AS number,IsCheck
FROM cdr
GROUP BY SipAccount,IsCheck
針對這個統計結果進行拆分(0表示未打分,1代表優秀,2代表合格,3代表不合格)
想要的最終結果如下:
所以最終要用到行拆分成三列,語句如下
SELECT SipAccount,
(CASE IsCheck WHEN 1 THEN number END) youxiu,
(CASE IsCheck WHEN 2 THEN number END) hege,
(CASE IsCheck WHEN 3 THEN number END) buhege
FROM
(SELECT SipAccount, COUNT(1) AS number,IsCheck
FROM cdr
GROUP BY SipAccount,IsCheck) AS a
現在結果是這樣的,你會發現雖然拆成了三列,但是最終結果還不是自己需要的,接下來就需要根據sipaccount來分組的同時對結果進行處理了。語句如下:
SELECT sipaccount,
IF(MAX(youxiu) IS NULL,0, MAX(youxiu)) youxiu,
IF(MAX(hege) IS NULL,0, MAX(hege)) hege,
IF(MAX(buhege) IS NULL,0, MAX(buhege)) buhege
FROM
(SELECT SipAccount,
(CASE IsCheck WHEN 1 THEN number END) youxiu,
(CASE IsCheck WHEN 2 THEN number END) hege,
(CASE IsCheck WHEN 3 THEN number END) buhege
FROM
(SELECT SipAccount, COUNT(1) AS number,IsCheck FROM cdr GROUP BY SipAccount,IsCheck) AS a) AS b
GROUP BY sipaccount
最終得到了這個結果。正式我們需要的格式
MySQL的IF函式(返回兩個不同結果的時候用IF,如果返回多個不同的結果,用case when)
格式:IF(Condition,A,B)
意義:當Condition為TRUE時,返回A;當Condition為FALSE時,返回B。
3.mysql 使用Case When 達到排序的效果
SELECT DISTINCT dev.deviceId, dev.deviceTypeCode, dev.mcuID, dev.workState, dtf.dcTypeCode from devicebase dev
ORDER BY
CASE dev.workstate
WHEN '3' THEN 0
WHEN '2' THEN 1
WHEN 'x' THEN 2
WHEN 'y' THEN 3
WHEN '1' THEN 4
ELSE 5 END, dev.workstate
或者
SELECT DISTINCT dev.deviceId, dev.deviceTypeCode, dev.mcuID, dev.workState, dtf.dcTypeCode,
CASE dev.workstate
WHEN '3' THEN 0
WHEN '2' THEN 1
WHEN 'x' THEN 2
WHEN 'y' THEN 3
WHEN '1' THEN 4
ELSE 5 END
AS state
from devicebase dev
ORDER BY state
4.利用case when實現分組(在網上搜索case when的時候找到的其他示例)
1-4級為一組,5,6級為一組,5-6級的優先處理,之後在處理1-4級
SELECT * FROM t_automatic_assign t ORDER BY t.RETRIEVE_STATUS DESC,
CASE WHEN DECISION_LEVEL = 5 OR DECISION_LEVEL = 6 THEN 1
ELSE 2 END t.CREATE_DATE ASC
5.利用case when實現細化分組
使用者查詢兩個狀態的列表,進行排序, 然後在第一個狀態和第二個狀態時按照lastLoginDate降序在第三個狀態按照tokencreatetime升序
SELECT * FROM yun_user WHERE type IN(2,1,99) ORDER BY type ASC,
CASE WHEN type = 2 OR type=1 THEN lastLoginDate END DESC,
CASE WHEN type=99 THEN tokencreatetime END ASC;
6.摘自其他部落格的一個例項
條件:某欄位代表該資料的狀態取值為非負整數,0表示無狀態。
需求:以該欄位升序排序,同時需要將值為0的資料放在最後。
首先我們看一下,表的結構:
正常的使用升序查詢結果是這樣的:
要讓“小赤”排在最後,可以這樣寫:
也可以這樣:(mysql的除數為0,則值為null,不會報錯)
還可以使用 CASE WHEN 再不影響查詢結果的前提下,改變排序的依據:
7.case when 返回的應該是一個字串型別的,而不是實際的那個變數的值的型別,例如有表結構
score表中,scores的屬性型別為float,數值如下:
按照分數scores排序:
SELECT * FROM `score` ORDER BY `scores`
利用case when排序,以為case when的條件為false,所以實際上也是按照scores排序,但是和order by scores排序的結果集順序不一致,如下圖:
如果想使用case when 並且按照數字大小排序可以這麼做,在case when 的返回值後面+0,即主動把case when的返回值變為數字型別:
case when的用法就總結到這裡,如果有不對