CASE WHEN的用法及總結
- 一、已知數據按照另外一種方式進行分組,分析
- 二、用一個SQL語句完成不同條件的分組
- 三、在Check中使用Case函數
- 四、根據條件有選擇的UPDATE
- 五、兩個表數據是否一致的檢查
- 六、在Case函數中使用合計函數
- 七、小結
Case具有兩種格式。簡單Case函數和Case搜索函數。
簡單Case函數
1 CASE sex 2 WHEN '1' THEN '男' 3 WHEN '2' THEN '女' 4 ELSE '其他' END
Case搜索函數
1 CASE WHEN sex = '1' THEN '男' 2 WHEN sex = '2' THEN '女' 3 ELSE '其他' END
兩種方式,可以實現相同的功能。簡單Case函數的寫法相對比較簡潔,但是和Case搜索函數相比,功能方面會有些限制,比如寫判斷式。還有一個需要注意的問題,Case函數只返回第一個符合條件的值,剩下的Case部分將會被自動忽略。
比如說,下面這段SQL,你永遠無法得到“第二類”這個結果
1 CASE WHEN col_1 IN ( 'a', 'b') THEN '第一類' 2 WHEN col_1 IN ('a') THEN '第二類' 3 ELSE'其他' END
一、已知數據按照另外一種方式進行分組,分析
判斷是不是在一個類中,然后聚合求出總數
1.求出每個省學生的個數
1 SELECT 2 CASE c.city 3 WHEN '哈爾濱' THEN 4 '黑龍江' 5 WHEN '沈陽' THEN 6 '遼寧' 7 WHEN '長春' THEN 8 '吉林' 9 WHEN '齊齊哈爾' THEN 10 '黑龍江' 11 ELSE 12 '其他地區' 13 END AS province, 14 sum(c.city_count) as stu_nums 15 FROM 16 ( 17 SELECT 18 city, 19 count(city) city_count 20 FROM 21 stu_info 22 GROUP BY 23 city 24 ) c 25 GROUP BY 26 CASE c.city 27 WHEN '哈爾濱' THEN 28 '黑龍江' 29 WHEN '沈陽' THEN 30 '遼寧' 31 WHEN '長春' THEN 32 '吉林' 33 WHEN '齊齊哈爾' THEN 34 '黑龍江' 35 ELSE 36 '其他地區' 37 END ORDER BY stu_nums desc;
結果顯示
2.判斷學生成績等級
1 select case 2 when grade >=60 and grade < 70 then 'D' 3 when grade >=70 and grade <80 then 'C' 4 when grade >=80 and grade <90 then 'B' 5 when grade >=90 and grade <=100 then 'A' 6 else 'E' end as level ,count(*) as stu_nums 7 from stu_grade 8 GROUP BY 9 case 10 when grade >=60 and grade < 70 then 'D' 11 when grade >=70 and grade <80 then 'C' 12 when grade >=80 and grade <90 then 'B' 13 when grade >=90 and grade <=100 then 'A' 14 else 'E' end ;
結果顯示
60分萬歲!!!
二、用一個SQL語句完成不同條件的分組
一行顯示出每個省份的男女人數
普通情況下,用UNION也可以實現用一條語句進行查詢。但是那樣增加消耗(兩個Select部分),而且SQL語句會比較長。下面是一個是用Case函數來完成這個功能的例子
1 select 2 province, 3 sum(case when sex= 'F' then nums else 0 end ) AS F, 4 sum(case when sex = 'M' then nums else 0 end ) AS M 5 from 6 stu_province 7 GROUP BY province 8 ORDER BY F desc;
結果顯示
這樣我們使用Select,完成對二維表的輸出形式,充分顯示了Case函數的強大。
三、在Check中使用Case函數
在Check中使用Case函數在很多情況下都是非常不錯的解決方法。可能有很多人根本就不用Check,那么我建議你在看過下面的例子之后也嘗試一下在SQL中使用Check。 下面我們來舉個例子 公司A,這個公司有個規定,女職員的工資必須高於1000塊。如果用Check和Case來表現的話,如下所示
THEN 1 ELSE 0 END ELSE 1 END = 1
如果單純使用
Check: CONSTRAINT check_salary CHECK ( sex = '2' AND salary > 1000 )
女職員的條件倒是符合了,男職員就無法輸入了。
四、根據條件有選擇的UPDATE
例,有如下更新條件
1.工資5000以上的職員,工資減少10%
2.工資在2000到4600之間的職員,工資增加15%
很容易考慮的是選擇執行兩次UPDATE語句,如下所示
--條件1
1 UPDATE emp 2 SET salary = salary * 0.9 3 WHERE 4 salary >= 5000;
執行后
--條件2
1 UPDATE Personnel SET salary = salary * 1.15 2 WHERE salary >= 2000 AND salary < 4600;
結果顯示
發現之前5000的員工編程5175,反而漲薪了,反之如果先執行漲薪在降薪,4600的會比之前少,如果想一個sql執行
1 UPDATE emp 2 SET salary = CASE 3 WHEN salary >= 2000 4 AND salary <= 4600 THEN 5 salary * 1.15 6 WHEN salary >= 5000 THEN 7 salary * 0.9 8 ELSE 9 salary 10 END;
結果顯示
這里要注意一點,最后一行的ELSE salary是必需的,要是沒有這行,不符合這兩個條件的人的工資將會被寫成NUll,那可就大事不妙了。在Case函數中Else部分的默認值是NULL,這點是需要注意的地方。
2.互換信息
需求,將Tom和Lily互換部門
1 UPDATE emp 2 SET dept_id = CASE 3 WHEN dept_id = 1 THEN 4 2 5 WHEN dept_id = 2 THEN 6 1 7 ELSE 8 dept_id 9 END;
結果顯示
五、兩個表數據是否一致的檢查
Case
函數不同於DECODE
函數。在Case
函數中,可以使用BETWEEN,LIKE,IS NULL,IN,EXISTS
等等。比如說使用IN,EXISTS
,可以進行子查詢,從而 實現更多的功能。 下面具個例子來說明,檢測員工是否在部門中,返回結果'Matched',如果沒有找到,返回結果'Unmatched'。 要實現下面這個功能,可以使用下面兩條語句
原始表還是之前的emp,新增dept表
emp
dept
1 SELECT 2 ename, 3 dept_id, 4 CASE 5 WHEN dept_id IN (SELECT id FROM dept) THEN 6 'Matched' 7 ELSE 8 'UnMatched' 9 END as isMatch 10 FROM 11 emp
結果顯示
六、在Case函數中使用合計函數
在當前的學生成績表中進行操作, 有的學生選擇了同時修幾門課程(100,200)也有的學生只選擇了一門課程(300,400,500)。選修多門課程的學生,要選擇一門課程作為主修,主修flag里面寫入 Y。只選擇一門課程的學生,主修flag為N
1.只選修一門課程的人,返回那門課程的ID
2.選修多門課程的人,返回所選的主課程ID
使用兩條語句分別查詢
--條件1:只選擇了一門課程的學生
1 SELECT 2 stu_id, 3 MAX(course_id) AS main_class 4 FROM 5 courses 6 GROUP BY 7 stu_id 8 HAVING 9 count(*) = 1
--條件2:選擇多門課程的學生
1 SELECT 2 stu_id, 3 course_id 4 FROM 5 courses 6 WHERE 7 isMain = 'Y'
3.Union下即可得出最終結果
1 SELECT 2 stu_id, 3 MAX(course_id) AS main_class 4 FROM 5 courses 6 GROUP BY 7 stu_id 8 HAVING 9 count(*) = 1 10 UNION 11 SELECT 12 stu_id, 13 course_id 14 FROM 15 courses 16 WHERE 17 isMain = 'Y' 18 order by stu_id
結果顯示
接下來使用case when then
1 SELECT 2 stu_id, 3 CASE 4 WHEN COUNT(*) = 1 THEN 5 Max(course_id) 6 ELSE 7 Max( 8 CASE 9 WHEN isMain = 'Y' THEN 10 course_id 11 ELSE 12 NULL 13 END 14 ) 15 END 16 FROM 17 courses 18 GROUP BY 19 stu_id; 20
效果同上
七、小結
select 與 case結合使用最大的好處有兩點
一是、可以把一列的數據,區分出其他列,例如一個班的列表,求出班級男女人數
二是、交換數據,例如學生學號反了
三是、一起更新數據,避免出現錯誤更新
四是、一個表的多個情況的union,可以考慮