?SQL 中 CASE 表達式的使用方式
1. 前言
CASE 表達式是從 SQL-92 標準開始被引入的。
在 CASE 表達式里,可以使用 BETWEEN 、LIKE和 < 、> 等便利的謂詞組合,以及能嵌套子查詢的 IN 和 EXISTS 謂詞。
2. 語法
CASE 表達式有 簡單 CASE 表達式(simple case expression) 和 搜索 CASE 表達式(searched case expression) 兩種寫法:
-- 簡單CASE 表達式 CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他'END -- 搜索CASE 表達式 CASE WHEN sex = '1' THEN '男' WHEN sex = '2' THEN '女' ELSE '其他' END
sex
列(字段)如果是 '1' ,那么結果為男;如果是 '2' ,那么結果為女。
3. 注意點
CASE在匹配給定條件時,發(fā)現(xiàn)為真的 WHEN 子句時,CASE 表達式的真假值判斷就會中止,而剩余的 WHEN 子句會被忽略。為了避免引起不必要的混亂,使用 WHEN 子句時要注意條件的排他性。
-- 例如,這樣寫的話,結果里不會出現(xiàn)“第二” CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END
- 統(tǒng)一各分支返回的數(shù)據(jù)類型: 一定要注意 CASE 表達式里各個分支返回的數(shù)據(jù)類型是否一致。某個分支返回字符型,而其他分支返回數(shù)值型的寫法是不正確的。
- 不要忘了寫 END: 不寫END是語法錯誤,這是不允許的。
- 養(yǎng)成寫 ELSE 子句的習慣: 與 END 不同,ELSE 子句是可選的,不寫也不會出錯。不寫 ELSE 子句時,CASE 表達式的執(zhí)行結果是 NULL 。
4. 分類匯總數(shù)據(jù)
SELECT CASE pref_name WHEN '德島' THEN '四國' WHEN '香川' THEN '四國' WHEN '愛媛' THEN '四國' WHEN '高知' THEN '四國' WHEN '福岡' THEN '九州' WHEN '佐賀' THEN '九州' WHEN '長崎' THEN '九州' END AS district, SUM(population) AS total FROM poptbl GROUP BY CASE pref_name WHEN '德島' THEN '四國' WHEN '香川' THEN '四國' WHEN '愛媛' THEN '四國' WHEN '高知' THEN '四國' WHEN '福岡' THEN '九州' WHEN '佐賀' THEN '九州' WHEN '長崎' THEN '九州' END;
5. 一條SQL實現(xiàn)不同條件的統(tǒng)計
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 poptlb GROUP By pref_name
6. 使用CHECK約束定義多個列的條件關系
假設某公司規(guī)定“女性員工的工資必須在 20 萬日元以下”,而在這個公司的人事表中,這條無理的規(guī)定是使用 CHECK 約束來描述的,代碼如下所示:
CONSTRAINT check_salary CHECK ( CASE WHEN sex = '2' THEN CASE WHEN salary <= 200000 THEN 1 ELSE 0 END ELSE 1 END = 1 )
7. 在UPDATE語句中進行條件分支
條件:
- 對當前工資為 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;
8. 生成交叉表
--- 使用IN謂詞 SELECT course_name AS '課程名', CASE WHEN courese_id IN (SELECT course_id FROM open_course WHERE mouth = '200706') THEN 'o' ELSE 'x' END AS '6 月' CASE WHEN courese_id IN (SELECT course_id FROM open_course WHERE mouth = '200707') THEN 'o' ELSE 'x' END AS '7 月' CASE WHEN courese_id IN (SELECT course_id FROM open_course WHERE mouth = '200708') THEN 'o' ELSE 'x' END AS '8 月' FROM course_master; --- 或者使用EXIST謂詞 SELECT CM.course_name, CASE WHEN EXISTS (SELECT course_id FROM OpenCourses OC WHERE month = 200706 AND OC.course_id = CM.course_id) THEN '○' ELSE '×' END AS "6 月", CASE WHEN EXISTS (SELECT course_id FROM OpenCourses OC WHERE month = 200707 AND OC.course_id = CM.course_id) THEN '○' ELSE '×' END AS "7 月", CASE WHEN EXISTS (SELECT course_id FROM OpenCourses OC WHERE month = 200708 AND OC.course_id = CM.course_id) THEN '○' ELSE '×' END AS "8 月" FROM CourseMaster CM;
9. CASE表達式中使用聚合函數(shù)
對于加入了多個社團的學生,通過將其“主社團標志”列設置為 Y 或者 N 來表明哪一個社團是他的主社團;對于只加入了一個社團的學生,將其“主社團標志”列設置為 N。
現(xiàn)需要查詢出所有學生加入的社團,若加入了多個則顯示主社團
SELECT std_id, CASE WHEN COUNT(*)==1 THEN MAX(club_id) ELSE MAX(CASE WHEN main_club_flg = 'Y' THEN club_id ELSE NULL END) END AS 'main_club' FROM student_club GROUP BY std_id
10. 按照自定義規(guī)則排序列
按照mark列排序,要求修正a b c d 的權重為 c b a d
SELECT mark FROM sort_test ORDER BY CASE mark WHEN 'a' THEN -1 WHEN 'b' THEN 1 WHEN 'c' THEN 2 WHEN 'd' THEN -2 END
到此這篇關于 SQL 中 CASE 表達式的使用方式的文章就介紹到這了,更多相關 SQL CASE 表達式內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
詳解如何校驗MySQL及Oracle時間字段合規(guī)性
這篇文章主要為大家介紹了如何校驗MySQL及Oracle時間字段合規(guī)性詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-06-06Mysql 5.7 服務下載安裝圖文教程(經(jīng)典版)
MySQL 5.7在諸多方面都進行了大幅的改進,主要在于安全性、靈活性、易用性、可用性和性能等幾個方面。這篇文章主要介紹了Mysql5.7服務下載安裝圖文教程(經(jīng)典版),需要的朋友可以參考下2016-09-09關于MySQL中“Insert into select“ 的死鎖情況分析
這篇文章主要介紹了關于MySQL中“Insert into select“ 的死鎖情況分析,死鎖是指兩個或者多個事務在同一資源上的相互占用,并請求鎖定對方占用的資源,從而導致惡性循環(huán)的現(xiàn)象,需要的朋友可以參考下2023-05-05Mysql中in和exists的區(qū)別?&?not?in、not?exists、left?join的相互轉換問題
這篇文章主要介紹了Mysql中in和exists的區(qū)別?&?not?in、not?exists、left?join的相互轉換,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09mysql建表報錯:invalid?default?value?for?'date'的解決方
最近遇到一個這樣的問題,出現(xiàn)了invalid default value for 'end_date'錯誤,所以下面這篇文章主要給大家介紹了關于mysql建表報錯:invalid?default?value?for?'date'的解決方法,需要的朋友可以參考下2022-12-12