目錄
- 一、什么是 CASE 運算式
- 二、CASE 運算式的語法
- 三、CASE 運算式的使用方法
- 四、CASE 運算式的書寫位置
本文介紹 SQL CASE 運算式,它是 SQL 中數一數二的重要功能,CASE 運算式的語法分為簡單 CASE 運算式和搜索 CASE 運算式兩種,
本文重點
CASE運算式分為簡單CASE運算式和搜索CASE運算式兩種,搜索CASE運算式包含簡單CASE運算式的全部功能,雖然
CASE運算式中的ELSE子句可以省略,但為了讓 SQL 陳述句更加容易理解,還是希望大家不要省略,
CASE運算式中的END不能省略,使用
CASE運算式能夠將SELECT陳述句的結果進行組合,雖然有些 DBMS 提供了各自特有的
CASE運算式的簡化函式,例如 Oracle 中的DECODE和 MySQL 中的IF,等等,但由于它們并非通用的函式,功能上也有些限制,因此有些場合無法使用,
一、什么是 CASE 運算式
本文將要學習的 CASE 運算式,和“1 + 1”或者“120 / 4”這樣的運算式一樣,是一種進行運算的功能,這就意味著 CASE 運算式也是函式的一種,
它是 SQL 中數一數二的重要功能,希望大家能夠在這里好好學習掌握,
CASE 運算式是在區分情況時使用的,這種情況的區分在編程中通常稱為 (條件)分支 [1],
二、CASE 運算式的語法
CASE 運算式的語法分為簡單 CASE 運算式和搜索 CASE 運算式兩種,但是,由于搜索 CASE 運算式包含了簡單 CASE 運算式的全部功能,因此本文只會介紹搜索 CASE 運算式,
想要了解簡單 CASE 運算式語法的讀者,可以參考本文末尾的“簡單 CASE 運算式”專欄,
下面就讓我們趕快來學習一下搜索 CASE 運算式的語法吧,
語法 16 搜索 CASE 運算式
CASE WHEN <求值運算式> THEN <運算式>
WHEN <求值運算式> THEN <運算式>
WHEN <求值運算式> THEN <運算式>
.
.
.
ELSE <運算式>
END
WHEN 子句中的“<求值運算式>”就是類似“列 = 值”這樣,回傳值為真值(TRUE/FALSE/UNKNOWN)的運算式,
我們也可以將其看作使用 =、!= 或者 LIKE、BETWEEN 等 謂詞 撰寫出來的運算式,
CASE 運算式會從對最初的 WHEN 子句中的“<求值運算式>”進行求值開始執行,
所謂求值,就是要調查該運算式的真值是什么,如果結果為真(TRUE),那么就回傳 THEN 子句中的運算式,CASE 運算式的執行到此為止,
如果結果不為真,那么就跳轉到下一條 WHEN 子句的求值之中,如果直到最后的 WHEN 子句為止回傳結果都不為真,那么就會回傳 ELSE 中的運算式,執行終止,
從 CASE 運算式名稱中的“運算式”我們也能看出來,上述這些整體構成了一個運算式,并且由于運算式最侄訓回傳一個值,因此 CASE 運算式在 SQL 陳述句執行時,也會轉化為一個值,
雖然使用分支眾多的 CASE 運算式撰寫幾十行代碼的情況也并不少見,但是無論多么龐大的 CASE 運算式,最后也只會回傳類似“1”或者“'渡邊先生'”這樣簡單的值,
三、CASE 運算式的使用方法
那么就讓我們來學習一下 CASE 運算式的具體使用方法吧,
例如我們來考慮這樣一種情況,現在 Product(商品)表中包含衣服、辦公用品和廚房用具 3 種商品型別,請大家考慮一下怎樣才能夠得到如下結果,
A :衣服
B :辦公用品
C :廚房用具
因為表中的記錄并不包含“A :”或者“B :”這樣的字串,所以需要在 SQL 中進行添加,我們可以使用 SQL 常用的函式 中學過的字串連接函式“||”來完成這項作業,
剩下的問題就是怎樣正確地將“A :”“B :”“C :”與記錄結合起來,這時就可以使用 CASE 運算式來實作了(代碼清單 41),
代碼清單 41 通過 CASE 運算式將 A ~ C 的字串加入到商品種類當中
SELECT product_name,
CASE WHEN product_type = '衣服'
THEN 'A:' || product_type
WHEN product_type = '辦公用品'
THEN 'B:' || product_type
WHEN product_type = '廚房用具'
THEN 'C:' || product_type
ELSE NULL
END AS abc_product_type
FROM Product;
執行結果:
product_name | abc_product_type
--------------+------------------
T恤衫 | A :衣服
打孔器 | B :辦公用品
運動T恤 | A :衣服
菜刀 | C :廚房用具
高壓鍋 | C :廚房用具
叉子 | C :廚房用具
擦菜板 | C :廚房用具
圓珠筆 | B :辦公用品
6 行 CASE 運算式代碼最后只相當于 1 列(abc_product_type)而已,大家也許有點吃驚吧!與商品種類(product_type)的名稱相對應,CASE 運算式中包含了 3 條 WHEN 子句分支,
最后的 ELSE NULL 是“上述情況之外時回傳 NULL”的意思,
ELSE 子句指定了應該如何處理不滿足 WHEN 子句中的條件的記錄,NULL 之外的其他值或者運算式也都可以寫在 ELSE 子句之中,
但由于現在表中包含的商品種類只有 3 種,因此實際上有沒有 ELSE 子句都是一樣的,
ELSE 子句也可以省略不寫,這時會被默認為 ELSE NULL,但為了防止有人漏讀,還是希望大家能夠顯式地寫出 ELSE 子句,
法則 3
雖然
CASE運算式中的ELSE子句可以省略,但還是希望大家不要省略,
此外,CASE 運算式最后的“END”是不能省略的,請大家特別注意不要遺漏,忘記書寫 END 會發生語法錯誤,這也是初學時最容易犯的錯誤,
法則 4
CASE運算式中的END不能省略,
四、CASE 運算式的書寫位置
CASE 運算式的便利之處就在于它是一個運算式,
之所以這么說,是因為運算式可以書寫在任意位置,也就是像“1 + 1”這樣寫在什么位置都可以的意思,
例如,我們可以像下面這樣利用 CASE 運算式將 SELECT 陳述句的結果中的行和列進行互換,
執行結果:
sum_price_clothes | sum_price_kitchen | sum_price_office
------------------+-------------------+-----------------
5000 | 11180 | 600
上述結果是根據商品種類計算出的銷售單價的合計值,通常我們將商品種類列作為 GROUP BY 子句的聚合鍵來使用,但是這樣得到的結果會以“行”的形式輸出,而無法以列的形式進行排列(代碼清單 42),
代碼清單 42 通常使用 GROUP BY 也無法實作行列轉換
SELECT product_type,
SUM(sale_price) AS sum_price
FROM Product
GROUP BY product_type;
執行結果:
product_type | sum_price
--------------+----------
衣服 | 5000
辦公用品 | 600
廚房用具 | 11180
我們可以像代碼清單 43 那樣在 SUM 函式中使用 CASE 運算式來獲得一個 3 列的結果,
代碼清單 43 使用 CASE 運算式進行行列轉換
-- 對按照商品種類計算出的銷售單價合計值進行行列轉換
SELECT SUM(CASE WHEN product_type = '衣服'
THEN sale_price ELSE 0 END) AS sum_price_clothes,
SUM(CASE WHEN product_type = '廚房用具'
THEN sale_price ELSE 0 END) AS sum_price_kitchen,
SUM(CASE WHEN product_type = '辦公用品'
THEN sale_price ELSE 0 END) AS sum_price_office
FROM Product;
在滿足商品種類(product_type)為“衣服”或者“辦公用品”等特定值時,上述 CASE 運算式輸出該商品的銷售單價(sale_price),不滿足時輸出 0,
對該結果進行匯總處理,就能夠得到特定商品種類的銷售單價合計值了,
在對 SELECT 陳述句的結果進行編輯時,CASE 運算式能夠發揮較大作用,
專欄
簡單 CASE 運算式
CASE運算式分為兩種,一種是本文學習的“搜索CASE運算式”,另一種就是其簡化形式——“簡單CASE運算式”,簡單
CASE運算式比搜索CASE運算式簡單,但是會受到條件的約束,因此通常情況下都會使用搜索CASE運算式,在此我們簡單介紹一下其語法結構,簡單
CASE運算式的語法如下所示,語法 A 簡單 CASE 運算式
CASE <運算式> WHEN <運算式> THEN <運算式> WHEN <運算式> THEN <運算式> WHEN <運算式> THEN <運算式> . . . ELSE <運算式> END與搜索
CASE運算式一樣,簡單CASE運算式也是從最初的WHEN子句開始進行,逐一判斷每個WHEN子句直到回傳真值為止,此外,沒有能夠回傳真值的
WHEN子句時,也會回傳ELSE子句指定的運算式,兩者的不同之處在于,簡單CASE運算式最初的“CASE<運算式>”也會作為求值的物件,下面就讓我們來看一看搜索
CASE運算式和簡單CASE運算式是如何實作相同含義的 SQL 陳述句的,將代碼清單 41 中的搜索
CASE運算式的 SQL 改寫為簡單CASE運算式,結果如下所示(代碼清單 A),代碼清單 A 使用 CASE 運算式將字串 A ~ C 添加到商品種類中
-- 使用搜索CASE運算式的情況(重寫代碼清單6-41) SELECT product_name, CASE WHEN product_type = '衣服' THEN 'A :' | |product_type WHEN product_type = '辦公用品' THEN 'B :' | |product_type WHEN product_type = '廚房用具' THEN 'C :' | |product_type ELSE NULL END AS abc_product_type FROM Product; -- 使用簡單CASE運算式的情況 SELECT product_name, CASE product_type WHEN '衣服' THEN 'A :' || product_type WHEN '辦公用品' THEN 'B :' || product_type WHEN '廚房用具' THEN 'C :' || product_type ELSE NULL END AS abc_product_type FROM Product;像“
CASE product_type”這樣,簡單CASE運算式在將想要求值的運算式(這里是列)書寫過一次之后,就無需在之后的WHEN子句中重復書寫“product_type”了,雖然看上去簡化了書寫,但是想要在
WHEN子句中指定不同列時,簡單CASE運算式就無能為力了,
專欄
特定的 CASE 運算式
由于
CASE運算式是標準 SQL 所承認的功能,因此在任何 DBMS 中都可以執行,但是,有些 DBMS 還提供了一些特有的
CASE運算式的簡化函式,例如 Oracle 中的DECODE、MySQL 中的IF等,使用 Oracle 中的
DECODE和 MySQL 中的IF將字串 A ~ C 添加到商品種類(product_type)中的 SQL 陳述句請參考代碼清單 B,代碼清單 B 使用 CASE 運算式的特定陳述句將字串 A ~ C 添加到商品種類中
Oracle
-- Oracle中使用DECODE代替CASE運算式 SELECT product_name, DECODE(product_type, '衣服', 'A :' || product_type, '辦公用品', 'B :' || product_type, '廚房用具', 'C :' || product_type, NULL) AS abc_product_type FROM Product;MySQL
-- MySQL中使用IF代替CASE運算式 SELECT product_name, IF( IF( IF(product_type = '衣服', CONCAT('A :', product_type), NULL) IS NULL AND product_type = '辦公用品', CONCAT('B :', product_type), IF(product_type = '衣服', CONCAT('A :', product_type), NULL)) IS NULL AND product_type = '廚房用具', CONCAT('C :', product_type), IF( IF(product_type = '衣服', CONCAT('A :', product_type), NULL) IS NULL AND product_type = '辦公用品', CONCAT('B :', product_type), IF(product_type = '衣服', CONCAT('A :', product_type), NULL))) AS abc_product_type FROM Product;但上述函式只能在特定的 DBMS 中使用,并且能夠使用的條件也沒有
CASE運算式那么豐富,因此并沒有什么優勢,希望大家盡量不要使用這些特定的 SQL 陳述句,
原文鏈接:https://www.developerastrid.com/sql/sql-case/
(完)
在 C 語言和 Java 等流行的編程語言中,通常都會使用
IF陳述句或者CASE陳述句,CASE運算式就是這些陳述句的 SQL 版本, ??
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/499174.html
標籤:SQL Server
