SQL基礎-第6章 函式、謂詞、CASE表示式
阿新 • • 發佈:2021-11-19
6-1 各種各樣的函式
函式的種類
函式,就是輸入某一值得到相應輸出結果的功能,輸入值稱為引數(parameter),輸出值稱為返回值
- 算術函式(用來進行數值計算的函式)
- 字串函式(用來進行字串操作的函式)
- 日期函式(用來進行日期操作的函式)
- 轉換函式(用來轉換資料型別和值的函式)
- 聚合函式(用來進行資料聚合的函式)
-- DDL :建立表 CREATE TABLE SampleMath (m NUMERIC (10,3), n INTEGER, p INTEGER); -- DML :插入資料 START TRANSACTION; INSERT INTO SampleMath(m, n, p) VALUES (500, 0, NULL); INSERT INTO SampleMath(m, n, p) VALUES (-180, 0, NULL); INSERT INTO SampleMath(m, n, p) VALUES (NULL, NULL, NULL); INSERT INTO SampleMath(m, n, p) VALUES (NULL, 7, 3); INSERT INTO SampleMath(m, n, p) VALUES (NULL, 5, 2); INSERT INTO SampleMath(m, n, p) VALUES (NULL, 4, NULL); INSERT INTO SampleMath(m, n, p) VALUES (8, NULL, 3); INSERT INTO SampleMath(m, n, p) VALUES (2.27, 1, NULL); INSERT INTO SampleMath(m, n, p) VALUES (5.555,2, NULL); INSERT INTO SampleMath(m, n, p) VALUES (NULL, 1, NULL); INSERT INTO SampleMath(m, n, p) VALUES (8.76, NULL, NULL); COMMIT; SELECT * FROM SampleMath;
算術函式
-
+(加法)
-
-(減法)
-
*(乘法)
-
/(除法)
-
ABS——絕對值 ABS(數值)
-- 計算數值的絕對值
SELECT m,
ABS(m) AS abs_col
FROM SampleMath;
- MOD——求餘 MOD(被除數,除數)
-- 計算除法( n ÷ p)的餘數
SELECT n, p,
MOD(n, p) AS mod_col
FROM SampleMath;
- ROUND——四捨五入 ROUND(物件數值,保留小數的位數)
-- 對m列的數值進行n列位數的四捨五入處理 SELECT m, n, ROUND(m, n) AS round_col FROM SampleMath;
字串函式
- CONCAT函式 CONCAT函式(字串1, 字串2)
-- 拼接字串
SELECT str1, str2, str3,
CONCAT(str1, str2, str3) AS str_concat
FROM SampleStr;
- LENGTH——字串長度 LENGTH(字串)
-- 計算字串長度
SELECT str1,
LENGTH(str1) AS len_str
FROM SampleStr;
- LOWER——小寫轉換 LOWER(字串)
-- 大寫轉換為小寫 SELECT str1, LOWER(str1) AS low_str FROM SampleStr;
- REPLACE——字串的替換
- REPLACE(物件字串,替換前的字串,替換後的字串)
-- 替換字串的一部分
SELECT str1, str2, str3,
REPLACE(str1, str2, str3) AS rep_str
FROM SampleStr;
- SUBSTRING——字串的擷取
- SUBSTRING(物件字串 FROM 擷取的起始位置 FOR 擷取的字元數)
-- 截取出字串中第3位和第4位的字元
SELECT str1,
SUBSTRING(str1 FROM 3 FOR 2) AS sub_str
FROM SampleStr;
- UPPER——大寫轉換 UPPER(字串)
-- 將小寫轉換為大寫
SELECT str1,
UPPER(str1) AS up_str
FROM SampleStr
WHERE str1 IN ('ABC', 'aBC', 'abc', '山田');
日期函式
- CURRENT_DATE——當前日期
-- 獲得當前日期
SELECT CURRENT_DATE;
- CURRENT_TIME——當前時間
-- 取得當前時間
SELECT CURRENT_TIME;
- CURRENT_TIMESTAMP——當前日期和時間
-- 取得當前日期和時間
SELECT CURRENT_TIMESTAMP;
- EXTRACT——擷取日期元素
- EXTRACT(日期元素 FROM 日期)
-- 擷取日期元素
SELECT CURRENT_TIMESTAMP,
EXTRACT(YEAR FROM CURRENT_TIMESTAMP) AS year,
EXTRACT(MONTH FROM CURRENT_TIMESTAMP) AS month,
EXTRACT(DAY FROM CURRENT_TIMESTAMP) AS day,
EXTRACT(HOUR FROM CURRENT_TIMESTAMP) AS hour,
EXTRACT(MINUTE FROM CURRENT_TIMESTAMP) AS minute,
EXTRACT(SECOND FROM CURRENT_TIMESTAMP) AS second;
轉換函式
- CAST——型別轉換
- CAST(轉換前的值 AS 想要轉換的資料型別)
- COALESCE——將NULL轉換為其他值
- COALESCE(資料1,資料2,資料3……)
-- 將字串型別轉換為數值型別
SELECT CAST('0001' AS SIGNED INTEGER) AS int_col;
-- 將字串型別轉換為日期型別
SELECT CAST('2009-12-14' AS DATE) AS date_col;
- 將NULL轉換為其他值
SELECT COALESCE(NULL, 1) AS col_1,
COALESCE(NULL, 'test', NULL) AS col_2,
COALESCE(NULL, NULL, '2009-11-01') AS col_3;
-- 使用SampleStr表中的列作為例子
SELECT COALESCE(str2, 'NULL')
FROM SampleStr;
6-2 謂詞
什麼是謂詞
謂詞就是需要滿足特定條件的函式,該條件就是返回值是真值
LIKE謂詞——字串的部分一致查詢
% 是代表“0 字元以上的任意字串”的特殊符號
_(下劃線)代表了“任意 1 個字元”
-- DDL :建立表
CREATE TABLE SampleLike
( strcol VARCHAR(6) NOT NULL,
PRIMARY KEY (strcol));
-- DML :插入資料
START TRANSACTION;
INSERT INTO SampleLike (strcol) VALUES ('abcddd');
INSERT INTO SampleLike (strcol) VALUES ('dddabc');
INSERT INTO SampleLike (strcol) VALUES ('abdddc');
INSERT INTO SampleLike (strcol) VALUES ('abcdd');
INSERT INTO SampleLike (strcol) VALUES ('ddabc');
INSERT INTO SampleLike (strcol) VALUES ('abddc');
COMMIT;
-- 使用LIKE進行前方一致查詢
SELECT *
FROM SampleLike
WHERE strcol LIKE 'ddd%';
-- 使用LIKE進行中間一致查詢
SELECT *
FROM SampleLike
WHERE strcol LIKE '%ddd%';
-- 使用LIKE進行後方一致查詢
SELECT *
FROM SampleLike
WHERE strcol LIKE '%ddd';
-- 使用LIKE和_(下劃線)進行後方一致查詢
SELECT *
FROM SampleLike
WHERE strcol LIKE 'abc__';
-- 查詢“abc+任意3個字元”的字串
SELECT *
FROM SampleLike
WHERE strcol LIKE 'abc___';
BETWEEN謂詞——範圍查詢
-- 選取銷售單價為100~ 1000日元的商品
SELECT product_name, sale_price
FROM Product
WHERE sale_price BETWEEN 100 AND 1000;
-- 選取出銷售單價為101 ~ 999日元的商品
SELECT product_name, sale_price
FROM Product
WHERE sale_price > 100
AND sale_price < 1000;
IS-NULL、IS-NOT-NULL——判斷是否為NULL
-- 選取出進貨單價( purchase_price)為NULL的商品
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price IS NULL;
-- 選取進貨單價( purchase_price)不為NULL的商品
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price IS NOT NULL;
IN謂詞——OR的簡便用法
使用IN 和 NOT IN 時是無法選取出NULL 資料的
-- 通過OR指定多個進貨單價進行查詢
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price = 320
OR purchase_price = 500
OR purchase_price = 5000;
-- 通過IN來指定多個進貨單價進行查詢
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price IN (320, 500, 5000);
-- 使用NOT IN進行查詢時指定多個排除的進貨單價進行查詢
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price NOT IN (320, 500, 5000);
使用子查詢作為IN謂詞的引數
-- 建立ShopProduct(商店商品)表的CREATE TABLE語句
CREATE TABLE ShopProduct
(shop_id CHAR(4) NOT NULL,
shop_name VARCHAR(200) NOT NULL,
product_id CHAR(4) NOT NULL,
quantity INTEGER NOT NULL,
PRIMARY KEY (shop_id, product_id))
DEFAULT CHARSET=utf8;
-- 向ShopProduct表中插入資料的INSERT語句
START TRANSACTION;
INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES ('000A', '東京', '0001', 30);
INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES ('000A', '東京', '0002', 50);
INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES ('000A', '東京', '0003', 15);
INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES ('000B', '名古屋', '0002', 30);
INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES ('000B', '名古屋', '0003', 120);
INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES ('000B', '名古屋', '0004', 20);
INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES ('000B', '名古屋', '0006', 10);
INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES ('000B', '名古屋', '0007', 40);
INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES ('000C', '大阪', '0003', 20);
INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES ('000C', '大阪', '0004', 50);
INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES ('000C', '大阪', '0006', 90);
INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES ('000C', '大阪', '0007', 70);
INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES ('000D', '福岡', '0001', 100);
COMMIT;
-- 使用子查詢作為IN的引數
-- 取得“在大阪店銷售的商品的銷售單價”
SELECT product_name, sale_price
FROM Product
WHERE product_id IN (SELECT product_id
FROM ShopProduct
WHERE shop_id = '000C');
-- 使用子查詢作為NOT IN的引數
-- 在東京店(000A)以外銷售的商品的銷售單價
SELECT product_name, sale_price
FROM Product
WHERE product_id NOT IN (SELECT product_id
FROM ShopProduct
WHERE shop_id = '000A');
EXIST謂詞
謂詞的作用就是“判斷是否存在滿足某種條件的記錄”
-- 使用 EXIST選取出“大阪店在售商品的銷售單價”
SELECT product_name, sale_price
FROM Product AS P
WHERE EXISTS (SELECT *
FROM ShopProduct AS SP
WHERE SP.shop_id = '000C'
AND SP.product_id = P.product_id);
-- 這樣的寫法也能得到相同的結果
SELECT product_name, sale_price
FROM Product AS P
WHERE EXISTS (SELECT 1 -- 這裡可以書寫適當的常數
FROM ShopProduct AS SP
WHERE SP.shop_id = '000C'
AND SP.product_id = P.product_id);
-- 使用NOT EXIST讀取出“東京店在售之外的商品的銷售單價”
SELECT product_name, sale_price
FROM Product AS P
WHERE NOT EXISTS (SELECT *
FROM ShopProduct AS SP
WHERE SP.shop_id = '000A'
AND SP.product_id = P.product_id);
6-3 CASE表示式
什麼是CASE表示式
一種進行運算的功能
CASE表示式的語法
CASE WHEN <求值表示式> THEN <表示式>
WHEN <求值表示式> THEN <表示式>
WHEN <求值表示式> THEN <表示式>
...
ELSE <表示式>
END
CASE表示式的使用方法
CONCAT("A : ",product_type)
簡單CASE表示式
CASE <表示式>
WHEN <表示式> THEN <表示式>
WHEN <表示式> THEN <表示式>
WHEN <表示式> THEN <表示式>
.
.
.
ELSE <表示式>
END
-- 通過CASE表示式將A ~ C的字串加入到商品種類當中
SELECT product_name,
CASE WHEN product_type = '衣服'
THEN CONCAT("A : ",product_type)
WHEN product_type = '辦公用品'
THEN CONCAT("B : ",product_type)
WHEN product_type = '廚房用具'
THEN CONCAT("C : ",product_type)
ELSE NULL
END AS abc_product_type
FROM Product;
-- 通常使用GROUP BY也無法實現行列轉換
SELECT product_type,
SUM(sale_price) AS sum_price
FROM Product
GROUP BY product_type;
使用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;
-- 使用簡單CASE表示式的情況
SELECT product_name,
CASE product_type
WHEN '衣服' THEN CONCAT("A : ",product_type)
WHEN '辦公用品' THEN CONCAT("B : ",product_type)
WHEN '廚房用具' THEN CONCAT("C : ",product_type)
ELSE NULL
END AS abc_product_type
FROM Product;
-- 使用 CASE表示式的特定語句將字串A ~ C新增到商品種類中
-- 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;
練習題
6.1 對本章中使用的 Product(商品)表執行如下 2 條 SELECT 語句,能夠得到什麼樣的結果呢?
①
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price NOT IN (500, 2800, 5000);
②
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price NOT IN (500, 2800, 5000, NULL);
①的答案
product_name | purchase_price |
---|---|
打孔器 | 320 |
擦菜板 | 790 |
②的答案:無法取出任何記錄
6.2 按照銷售單價( sale_price)對練習 6.1 中的 Product(商品)表中的商品進行如下分類。
- 低檔商品:銷售單價在1000日元以下(T恤衫、辦公用品、叉子、擦菜板、 圓珠筆)
- 中檔商品:銷售單價在1001日元以上3000日元以下(菜刀)
- 高檔商品:銷售單價在3001日元以上(運動T恤、高壓鍋)
請編寫出統計上述商品種類中所包含的商品數量的 SELECT 語句,結果如下所示。
執行結果
low_price | mid_price | high_price |
---|---|---|
5 | 1 | 2 |
SELECT
SUM(CASE WHEN sale_price <= 1000 THEN 1 ELSE 0 END) as low_price,
SUM(CASE WHEN sale_price > 1000 AND sale_price <= 3000 THEN 1 ELSE 0 END) as mid_price,
SUM(CASE WHEN sale_price > 3000 THEN 1 ELSE 0 END) as high_price
FROM Product;