日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

case when的判断顺序_CASE 表达式

發布時間:2025/3/21 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 case when的判断顺序_CASE 表达式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、語法及作用

使用CASE表達式可以幫助我們解決復雜的查詢問題,相當于條件判斷的函數,判斷每一行是不是滿足條件。

CASE WHEN (判斷表達式) THEN (表達式)WHEN (判斷表達式) THEN (表達式)WHEN (判斷表達式) THEN (表達式)....ELSE(表達式) END;

CASE 表達式會從對最初的WHEN子句中的“< 求值表達式 >”進行求值開始執行。所謂求值,就是要調查該表達式的真值是什么。如果結果為真(TRUE),那么就返回THEN子句中的表達式,CASE表達式的執行到此為止。如果結果不為真,那么就跳轉到下一條WHEN子句的求值之中。 如果直到最后的WHEN子句為止返回結果都不為真,那么就會返回ELSE中的表達式,執行終止。

二、注意事項

  • 在發現為真的 WHEN 子句時, CASE 表達式的真假值判斷就會中止,而剩余的 WHEN 子句會被忽略。因此,為了避免引起不必要的混亂,使用 WHEN 子句時要注意條件的排他性。
  • CASE 表達式里各個分支返回的數據類型必須一致,如果不一致,則需使用CAST()函數轉換數據類型。
  • 雖然CASE表達式中的ELSE子句可以省略,但為了讓SQL語句更加容易理解,還是盡量不要省略。
  • CASE 表達式中的 END 不能省略。
  • 使用CASE表達式能夠將SELECT語句的結果進行組合。

三、適用情況

3.1 將已有編號方式轉換為新的方式并統計

例如,統計下表 PopTbl 中的內容,得出如右表“統計結果”所示的結果。

首先,可以通過定義一個包含“地區編號”列的視圖來實現。但是這種方法需要添加的行的數量將等同于統計對象的編號個數,而且很難動態地修改。因此,可以使用CASE表達式來實現:

SELECT CASE WHEN pref_name IN ('德島', '香川', '愛媛', '高知') THEN '四國'WHEN pref_name IN ('福岡', '佐賀', '長崎') THEN '九州'ELSE '其他'END AS district,SUM(population) AS population FROM PopTbl GROUP BY CASE WHEN pref_name IN ('德島', '香川', '愛媛', '高知') THEN '四國'WHEN pref_name IN ('福岡', '佐賀', '長崎') THEN '九州'ELSE '其他'END ORDER BY population DESC;

這里的關鍵在于將SELECT子句里的CASE表達式復制到 GROUP BY 子句里。后期修改時有可能只改了一處而忘了另一處。因此,可以在 GROUP BY 子句中引用 SELECT 子句中定義的別名 (如下代碼所示),這樣寫出來的 SQL 語句確實非常簡潔,而且可讀性也很好 。

SELECT CASE WHEN pref_name IN ('德島', '香川', '愛媛', '高知') THEN '四國'WHEN pref_name IN ('福岡', '佐賀', '長崎') THEN '九州'ELSE '其他'END AS district,SUM(population) AS population FROM PopTbl GROUP BY district ORDER BY population DESC;

嚴格來說,這種寫法是違反標準 SQL 的規則的,因為 GROUP BY 子句比 SELECT 語句先執行。事實上,在 Oracle、DB2、 SQL Server 等數據庫里采用這種寫法時就會出錯。 不過在 PostgreSQL 和 MySQL 中,這個查詢語句就可以順利執行。這是因為,這些數據庫在執行查詢語句時,會先對 SELECT 子句里的列表進行掃描,并對列進行計算。不過因為這是違反標準的寫法,所以這里不強烈推薦大家使用。

3.2 行列轉換:在聚合函數中使用CASE WHEN 表達式

3.2.1 統計下表 PopTbl2 中的內容,得出如右表“統計結果”所示的結果。

SELECT pref_name,SUM(CASE WHEN sex = 1 THEN population ELSE 0 END) AS '男性人口',SUM(CASE WHEN sex = 0 THEN population ELSE 0 END) AS '女性人口' FROM PopTbl2 GROUP BY pref_name;

3.2.2 統計 PopTbl2 表中的容,得出如下表所示的結果。

SELECT CASE WHEN sex = 1 THEN 'male' ELSE 'female' END AS sex2, SUM(population) AS 'total', SUM(CASE WHEN pref_name = '德島' THEN population ELSE 0 END) AS '德島', SUM(CASE WHEN pref_name = '香川' THEN population ELSE 0 END) AS '香川', SUM(CASE WHEN pref_name = '愛媛' THEN population ELSE 0 END) AS '愛媛', SUM(CASE WHEN pref_name = '高知' THEN population ELSE 0 END) AS '高知', SUM(CASE WHEN pref_name IN ('德島', '香川', '愛媛', '高知') THEN population ELSE 0 END) AS '四國' FROM PopTbl2 GROUP BY sex2;

3.3 表之間的數據匹配:在 CASE WHEN 表達式中使用子查詢

方法一:子查詢 (X 和 O 表示)

SELECT course_name,CASE WHEN course_id IN (SELECT course_id FROM OpenCourses WHERE month = '200706')THEN 'O' ELSE 'X' END AS 'June',CASE WHEN course_id IN (SELECT course_id FROM OpenCourses WHERE month = '200707')THEN 'O' ELSE 'X' END AS 'July',CASE WHEN course_id IN (SELECT course_id FROM OpenCourses WHERE month = '200708')THEN 'O' ELSE 'X' END AS 'August' FROM CourseMaster;

方法二:聯結 (0 和 1表示)

SELECT a.course_name,MAX(CASE WHEN b.month = '200706' THEN 1 ELSE 0 END) AS 'June',MAX(CASE WHEN b.month = '200707' THEN 1 ELSE 0 END) AS 'July',MAX(CASE WHEN b.month = '200708' THEN 1 ELSE 0 END) AS 'August' FROM CourseMaster AS a LEFT JOIN OpenCourses AS b ON a.course_id = b.course_id GROUP BY a.course_name;

3.4 在 CASE 表達式中使用聚合函數

如表 StudentClub 所示,這張表的主鍵是“學號、社團 ID”,存儲了學生和社團之間多對多的關系。有的學生同時加入了多個社團(如學號為 100、200 的學生),有的學生只加入了某一個社團(如學號為 300、400、500 的學生)。對于加入了多個社團的學生,我們通過將其“主社團標志”列設置為 Y 或者 N 來表明哪一個社團是他的主社團;對于只加入了一個社團的學生,我們將其“主社團標志”列設置為 N。

接下來,我們需要查詢獲取只加入了一個社團的學生的社團 ID 以及獲取加入了多個社團的學生的主社團 ID,并將結果存放在一個表中。

方法一:UNION ALL

SELECT std_id, MAX(club_id) AS 'main_club' FROM StudentClub GROUP BY std_id HAVING COUNT(club_id) = 1 UNION ALL SELECT std_id, club_id AS 'main_club' FROM StudentClub WHERE main_club_flg = 'Y' ORDER BY std_id;

方法二:CASE WHEN 表達式

SELECT std_id, CASE WHEN COUNT(club_id) = 1 THEN MAX(club_id)ELSE MAX(CASE WHEN main_club_flg = 'Y' THEN club_id ELSE NULL END) END AS 'main_club' FROM StudentClub GROUP BY std_id;

3.5 多列數據的最大值

針對每一個key_col,取出x、y、z中最大的值 (取出每一行的最大值)

方法一:自己想的

SELECT key_col,CASE WHEN x > y AND x > z THEN xWHEN y > x AND y > z THEN yELSE zEND AS 'max_col' FROM Greatests;

方法二:窮盡討論

SELECT key_col,CASE WHEN CASE WHEN x < y THEN x ELSE y END < z THEN z ELSECASE WHEN x < y THEN y ELSE x ENDEND AS greatest FROM Greatests;

方法三:運用 UNION ALL 進行行列轉換

SELECT key_col, MAX(col) AS greatest FROM(SELECT key_col, x AS col FROM GreatestsUNION ALLSELECT key_col, y AS col FROM GreatestsUNION ALLSELECT key_col, z AS col FROM Greatests) AS a GROUP BY key_col;

方法四:GREATEST() 函數

SELECT key_col, GREATEST(x, y, z) AS greatest FROM Greatests;

GREATEST() 函數介紹:

https://www.w3schools.com/sql/func_mysql_greatest.asp?www.w3schools.com

3.6 在 ORDER BY 語句中使用 CASE WHEN 表達式

3.6.1 針對3.5中的結果,將結果按照 B-A-D-C的順序排序

SELECT key_col,CASE WHEN CASE WHEN x < y THEN x ELSE y END < z THEN z ELSECASE WHEN x < y THEN y ELSE x ENDEND AS greatest FROM Greatests ORDER BY (CASE WHEN key_col = 'B' THEN 1WHEN key_col = 'A' THEN 2WHEN key_col = 'D' THEN 3ELSE 4 END);

3.6.2 如果job是"SALESMAN",則根據"comm"排序,否則根據"sal"排序

方法1:

SELECT ename, sal, job, comm FROM emp ORDER BY CASE WHEN job = 'SALESMAN' THEN commELSE salEND;

方法2:

SELECT ename, sal, job, comm,CASE WHEN job = 'SALESMAN' THEN commELSE salEND AS ordered FROM emp ORDER BY 5;

3.7 使用 CASE WHEN 語句在 UPDATE 語句里進行條件分支:

例如:對公司工資表中(Salaries)的員工工資(salary)進行更新:對當前工資為 30 萬日元以上的員工,降薪 10%;對當前工資為 25 萬日元以上且不滿 28 萬日元的員工,加薪 20%。

UPDATE SalariesSET salary = CASE WHEN salary > 300000 THEN salary * 0.9WHEN salary >250000 AND salary <280000 THEN salary * 1.2ELSE salaryEND;

3.8 調換主鍵值:

通常,當我們想調換主鍵值 a 和 b 時,需要將主鍵值臨時轉換成某個中間值。使用這種方法時需要執行 3 次 UPDATE 操作:

-- 1. 將 a 轉換為中間值 d UPDATE SomeTable SET p_key = 'd' WHERE p_key = 'a';-- 2.將b調換為a UPDATE SomeTable SET p_key = 'a' WHERE p_key = 'b';-- 3.將d調換為b UPDATE SomeTable SET p_key = 'b' WHERE p_key = 'd';

但是,如果使用 CASE 表達式,1 次就可以做到:

UPDATE SomeTable SET p_key = CASE WHEN p_key = 'a' THEN 'b'WHEN p_key = 'b' THEN 'a'ELSE p_keyEND;

一般來說需要進行這樣的調換大多是因為表的設計出現了問題,所以請先重新審視一下表的設計,去掉不必要的約束。

四、練習

表關系請參考如下文章 (SQL面試50題) 中的四張表

shanshant:SQL面試50題?zhuanlan.zhihu.com

練習一:查詢每門課程的及格人數和不及格人數

方法一:自己寫的

SELECT c_id, SUM(及格) AS 及格人數, SUM(不及格) AS 不及格人數 FROM (SELECT c_id,CASE WHEN score >=60 THEN 1 ELSE 0 END AS '及格',CASE WHEN score <60 THEN 1 ELSE 0 END AS '不及格'FROM scores) AS c GROUP BY c_id;

方法二:參考猴子老師的

SELECT c_id, SUM(CASE WHEN score >= 60 THEN 1ELSE 0END) AS 及格人數, SUM(CASE WHEN score < 60 THEN 1ELSE 0END) AS 不及格人數 FROM scores GROUP BY c_id;

練習二:使用分段 [100-85], [85-70], [70-60], [<60]來統計各科成績,分別統計:各分數段人數,課程號和課程名稱。

SELECT a.c_id, b.c_name, SUM(CASE WHEN score >= 85 THEN 1ELSE 0END) AS 85至100分數段, SUM(CASE WHEN score >= 70 AND score < 85 THEN 1ELSE 0END) AS 70至85分數段, SUM(CASE WHEN score >= 60 AND score < 70 THEN 1ELSE 0END) AS 60至70分數段, SUM(CASE WHEN score < 60 THEN 1ELSE 0END) AS 不及格 FROM scores AS a RIGHT JOIN classes AS b ON a.c_id = b.id GROUP BY a.c_id, b.c_name;

總結

以上是生活随笔為你收集整理的case when的判断顺序_CASE 表达式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。