一、簡介
??今天我們主要是講講case…when…then…end的用法,它主要分成兩類:
- 簡單Case函數
- Case搜索函數
假設我們數據庫有一個員工信息表表如下:
CREATE TABLE `tb_employee` (
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`emp_code` int unsigned NOT NULL DEFAULT '0' COMMENT '員工編碼',
`emp_name` varchar(20) NOT NULL DEFAULT '' COMMENT '員工姓名',
`gender` char(1) NOT NULL DEFAULT '1' COMMENT '性別(1:男0:女)',
`dep_code` int NOT NULL DEFAULT '0' COMMENT '部門',
`job` varchar(20) NOT NULL DEFAULT '' COMMENT '工作',
`age` tinyint NOT NULL DEFAULT '0' COMMENT '年齡',
`salary` double(8,2) NOT NULL DEFAULT '0.00' COMMENT '工資',
`hire_date` date DEFAULT NULL COMMENT '入職時間',
`manage_code` int DEFAULT NULL COMMENT '所屬領導',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
PRIMARY KEY (`id`),
KEY `idx_emp_code` (`emp_code`),
KEY `idx_manage_code` (`manage_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='員工信息表';
接下來希望你看文章時不要因為sql長而害怕,都是些重復的東西而已,請放寬心態(tài)看待。
二、簡單Case函數
2.1、語法定義
??語法如下:
CASE '字段名'
WHEN '字段值1' THEN '結果1'
WHEN '字段值2' THEN '結果2'
WHEN '字段值3' THEN '結果3'
ELSE '其他結果'
END
?? 字段名 就是數據庫表中字段, 字段值 就是這個字段存儲的值, 結果 就是你希望得到的結果。
2.2、簡單函數形式
??比如我們要 查詢一份基本的員工信息 ,數據庫里存儲的是1或者0,我們肯定不會顯示1或者0,而是對應的性別(男或者女),這樣更加的直觀。從上面 tb_student 表的定義我們知道字段 gender ,1表示男,0表示女,默認值是1,這個時候我們就可以利用 case…when…then…end 來實現
SELECT
emp_code AS '員工編號',
emp_name AS '員工姓名',
(CASE gender
WHEN 1 THEN '男'
WHEN 0 THEN '女'
ELSE '未知'
END) AS '性別',
salary AS '工資'
FROM tb_employee;
??還有些人覺得 else 可以不要,但是不建議這樣做,假設數據庫沒有設置默認值,程序又沒有設置值,那就變成空了,又或者有個傻瓜蛋把 gender 的值改成了2呢?畢竟 else 是你的一個兜底。尤其是在一些字段可能會擴展的類型的時候, else 就顯得很重要了。
??一般會把 case 到 end 用括號包括,這樣也便于解讀或者使用別名等。
三、Case搜索函數
3.1、語法定義
??語法如下:
CASE WHEN '表達式1' THEN '結果1'
WHEN '表達式2' THEN '結果2'
WHEN '表達式3' THEN '結果3'
ELSE '其他結果'
END
?? 字段名 就是數據庫表中字段, 字段值 就是這個字段存儲的值, 結果 就是你希望得到的結果。在Case函數中,表達式可以使用 BETWEEN,LIKE,IS NULL,IN,EXISTS 等等
3.2、簡單用法
??比如我們還是用 查詢一份基本的員工信息 舉例看基本使用。
SELECT
emp_code AS '員工編號',
emp_name AS '員工姓名',
(CASE
WHEN gender=1 THEN '男'
WHEN gender=0 THEN '女'
ELSE '未知'
END) AS '性別',
salary AS '工資'
FROM tb_employee;
??這樣你會發(fā)現和上面簡單Case函數形式差別很小,確實,如果只是等值表達式,區(qū)別很小,并且簡單表達式還簡單些。這里這么寫只是先混個臉熟,根本沒有把表達式的作用發(fā)揮出來。
3.3、分組
??老板想看看公司里員工的薪資架構是否合理, 需要提供一份明細,查詢每個人對應的級別 ,級別規(guī)劃如下:
工資范圍 | 工資級別 |
---|---|
員工工資小于3000的 | 入門 |
員工工資大于等于3000并且小于15000的 | 初級 |
員工工資大于等于15000并且小于25000的 | 中級 |
員工工資大于等于25000并且小于50000的 | 高級 |
員工工資大于等于50000 | 特級 |
則我們可以使用 case…when…then…end 這一語法完成這個查詢。
SELECT
emp_code AS '員工編號',
emp_name AS '員工姓名',
salary AS '員工工資',
(CASE
WHEN salary < 3000 THEN '入門級'
WHEN salary >= 3000 AND salary < 15000 THEN '初級'
WHEN salary >= 15000 AND salary < 25000 THEN '中級'
WHEN salary >= 25000 AND salary < 50000 THEN '高級'
ELSE '特級'
END) AS '工資級別'
FROM tb_employee;
??這里的表達式,使用了算術表達式,and表達式,還要between…and 表達式,這里只是告訴大家可以用,實際沒必要混著用。
3.4、分組+計數
??老板想看看 公司對應的每個工資級別分別有多少人 。
SELECT
(CASE
WHEN salary < 3000 THEN '入門級'
WHEN salary >= 3000 AND salary < 15000 THEN '初級'
WHEN salary >= 15000 AND salary < 25000 THEN '中級'
WHEN salary >= 25000 AND salary < 50000 THEN '高級'
ELSE '特級'
END) as 'levels',
count(*) AS '總人數'
FROM tb_employee
GROUP BY levels;
??如果老板還想 細分到每個部門,及每個部門對應工資級別的總人數 ,假設部門編號從10到14分別對應則:
編號 | 部門 |
---|---|
10 | 總經辦 |
11 | 財務 |
12 | 技術 |
13 | 測試 |
14 | 運維 |
??那么我們只需要先按部門分組,再按工資級別分組即可
SELECT
dep_code AS '部門編號',
(CASE
WHEN dep_code=10 THEN '總經辦'
WHEN dep_code=11 THEN '財務'
WHEN dep_code=12 THEN '技術'
WHEN dep_code=13 THEN '測試'
WHEN dep_code=14 THEN '運維'
ELSE '其他'
END) AS '部門',
(CASE
WHEN salary < 3000 THEN '入門級'
WHEN salary >= 3000 AND salary < 15000 THEN '初級'
WHEN salary >= 15000 AND salary < 25000 THEN '中級'
WHEN salary >= 25000 AND salary < 50000 THEN '高級'
ELSE '特級'
END) AS 'levels',
count(*) as '總人數'
FROM tb_employee
GROUP BY dep_code,levels;
??實際中對應部門名稱肯定是以連表查詢居多,我這里是為了演示,順便加深 case…when…then…end 用法的使用
3.5、分組+匯總
??如果老板現在想知道, 每個部門的總工資,及每個部門中每個工資級別每個月總工資是多少 。小伙伴們想到的可能是先按部門分組,再按性別分組,然后再匯總。如果是一條記錄顯示這個結果,我相信很多小伙伴也不知道怎么去查詢。
??我們不著急,我們先查個簡單的,查詢每個部門的男生總數和女生總數,以及部門的總人數。那么 case…when…then…end 的作用又來了。
SELECT
dep_code AS '部門編號',
(CASE
WHEN dep_code=10 THEN '總經辦'
WHEN dep_code=11 THEN '財務'
WHEN dep_code=12 THEN '技術'
WHEN dep_code=13 THEN '測試'
WHEN dep_code=14 THEN '運維'
ELSE '其他'
END) AS '部門',
SUM((CASE WHEN gender = 1 THEN 1 ELSE 0 END)) AS '男生人數',
SUM((CASE WHEN gender = 0 THEN 1 ELSE 0 END)) AS '女生人數',
COUNT(*) AS '部門總人數'
FROM
tb_employee
GROUP BY dep_code;
??也許即算看了代碼,也許還是有不理解的,為什么兩個總數在一行。
- count(*)按部門分組,同一個部門的每一條記錄都會加入結果集
- case…when…then…end這個是同一個部門中,只有滿足條件才會記錄到結果集,我們這里滿足就記為1,不滿足,記為0,然后使用sum函數匯總
??了解了上面這個后,我們之前那個需求 每個部門的總工資,及每個部門中每個工資級別每個月總工資是多少 就容易理解了,查詢如下:
SELECT
dep_code AS '部門編號',
(CASE
WHEN dep_code=10 THEN '總經辦'
WHEN dep_code=11 THEN '財務'
WHEN dep_code=12 THEN '技術'
WHEN dep_code=13 THEN '測試'
WHEN dep_code=14 THEN '運維'
ELSE '其他'
END) AS '部門',
SUM(salary) AS '總工資',
SUM((CASE WHEN salary <= 3000 THEN salary ELSE 0 END)) AS '入門總工資',
SUM((CASE WHEN salary > 3000 AND salary < 15000 THEN salary ELSE 0 END)) AS '初級總工資',
SUM((CASE WHEN salary >= 15000 AND salary < 25000 THEN salary ELSE 0 END)) AS '中級總工資',
SUM((CASE WHEN salary >= 25000 AND salary <= 50000 THEN salary ELSE 0 END)) AS '高級總工資',
SUM((CASE WHEN salary > 50000 THEN salary ELSE 0 END)) AS '特級總工資'
FROM
tb_employee
GROUP BY dep_code;
??其實還算可以更詳細 每個部門的總人數,總工資,及每個部門中每個工資級別的人數及每個級別對應的總工資是多少
SELECT
dep_code AS '部門編號',
(CASE
WHEN dep_code=10 THEN '總經辦'
WHEN dep_code=11 THEN '財務'
WHEN dep_code=12 THEN '技術'
WHEN dep_code=13 THEN '測試'
WHEN dep_code=14 THEN '運維'
ELSE '其他'
END) AS '部門',
COUNT(*) AS '總人數',
SUM(salary) AS '總工資',
SUM((CASE WHEN salary <= 3000 THEN 1 ELSE 0 END)) AS '入門總人數',
SUM((CASE WHEN salary > 3000 AND salary < 15000 THEN 1 ELSE 0 END)) AS '初級總人數',
SUM((CASE WHEN salary >= 15000 AND salary < 25000 THEN 1 ELSE 0 END)) AS '中級總人數',
SUM((CASE WHEN salary >= 25000 AND salary <= 50000 THEN 1 ELSE 0 END)) AS '高級總人數',
SUM((CASE WHEN salary > 50000 THEN 1 ELSE 0 END)) AS '特級總人數',
SUM((CASE WHEN salary <= 3000 THEN salary ELSE 0 END)) AS '入門總工資',
SUM((CASE WHEN salary > 3000 AND salary < 15000 THEN salary ELSE 0 END)) AS '初級總工資',
SUM((CASE WHEN salary >= 15000 AND salary < 25000 THEN salary ELSE 0 END)) AS '中級總工資',
SUM((CASE WHEN salary >= 25000 AND salary <= 50000 THEN salary ELSE 0 END)) AS '高級總工資',
SUM((CASE WHEN salary > 50000 THEN salary ELSE 0 END)) AS '特級總工資'
FROM
tb_employee
GROUP BY dep_code;
??相當于兩個例子合并了,還可以計算平均工資等就不一一列舉了。
3.6、更新語句
??公司部門編號從10到20,公司對員工的工資進行調整,除去部門10以外
工資范圍 | 工資級別 |
---|---|
員工工資小于3000的 | 漲薪400 |
員工工資大于等于3000并且小于15000的 | 漲薪20% |
員工工資大于等于15000并且小于25000的 | 漲薪10% |
員工工資大于等于25000并且小于50000的 | 不變 |
員工工資大于等于50000 | 降薪10% |
UPDATE tb_employee
SET
salary = (CASE
WHEN salary <= 3000 THEN salary + 400
WHEN salary > 3000 AND salary <= 15000 THEN salary * 1.2
WHEN salary > 15000 AND salary < 25000 THEN salary * 1.1
WHEN salary > 50000 THEN salary * 0.9
ELSE salary
END)
where dep_code > 10;
3.7、子查詢
??比如對賬時有本地記錄 tb_local_record 和外部記錄 tb_outside_record ,通過查詢看哪些本地記錄沒有對應的外部記錄。
SELECT
tranSeq as '交易流水',
(CASE
WHEN tranSeq IN (SELECT tranSeq FROM tb_outside_record) THEN '匹配'
ELSE '未匹配'
END) as '是否匹配'
FROM tb_local_record;
或者文章來源:http://www.zghlxwxcb.cn/news/detail-767215.html
SELECT
lr.tranSeq as '交易流水',
(CASE
WHEN EXISTS (SELECT osr.tranSeq FROM tb_outside_record osr
WHERE osr.tranSeq = lr.tranSeq) THEN '匹配'
ELSE '未匹配'
END) as '是否匹配'
FROM tb_local_record lr;
結語
??case…when…then…end的用法還有很多,比如還能聯合count函數,但是一般有以上的方式,基本上就夠你工作所需了。文章來源地址http://www.zghlxwxcb.cn/news/detail-767215.html
到了這里,關于MySQL之case...when...then...end的詳細使用的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!