目錄
- 一、什么是 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],
KEYWORD
CASE運算式分支(條件分支)
二、CASE 運算式的語法
CASE 運算式的語法分為簡單 CASE 運算式和搜索 CASE 運算式兩種,但是,由于搜索 CASE 運算式包含了簡單 CASE 運算式的全部功能,因此本文只會介紹搜索 CASE 運算式,想要了解簡單 CASE 運算式語法的讀者,可以參考本文末尾的“簡單 CASE 運算式”專欄,
KEYWORD
簡單
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 中的運算式,執行終止,
KEYWORD
WHEN子句求值
THEN子句
ELSE
從 CASE 運算式名稱中的“運算式”我們也能看出來,上述這些整體構成了一個運算式,并且由于運算式最侄訓回傳一個值,因此 CASE 運算式在 SQL 陳述句執行時,也會轉化為一個值,雖然使用分支眾多的 CASE 運算式撰寫幾十行代碼的情況也并不少見,但是無論多么龐大的 CASE 運算式,最后也只會回傳類似“1”或者“' 渡邊先生 '”這樣簡單的值,
三、CASE 運算式的使用方法
那么就讓我們來學習一下 CASE 運算式的具體使用方法吧,例如我們來考慮這樣一種情況,現在 Product(商品)表中包含衣服、辦公用品和廚房用具 3 種商品型別,請大家考慮一下怎樣才能夠得到如下結果,
A :衣服
B :辦公用品
C :廚房用具
因為表中的記錄并不包含“A :”或者“B :”這樣的字串,所以需要在 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 子句都是一樣的,
KEYWORD
ELSE NULL
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等,KEYWORD
DECODE函式(Oracle)
IF函式(MySQL)使用 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 陳述句,
請參閱
- 各種各樣的函式
- SQL 謂詞
- CASE 運算式
(完)
在 C 語言和 Java 等流行的編程語言中,通常都會使用
IF陳述句或者CASE陳述句,CASE運算式就是這些陳述句的 SQL 版本, ??
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/374444.html
標籤:SQL Server
上一篇:SQL 謂詞簡介
