《SQL基礎(chǔ)教程》學(xué)習(xí)筆記Ch6

6函數(shù)、謂詞、CASE表達式

6-1各種各樣的函數(shù)

函數(shù)的種類

函數(shù):輸入某一值得到相應(yīng)輸出結(jié)果的功能,輸入值稱為參數(shù)(parameter), 輸出值稱為返回值

●算術(shù)函數(shù)(用來進行數(shù)值計算的函數(shù))
● 字符串函數(shù)(用來進行字符串操作的函數(shù))
● 日期函數(shù)(用來進行日期操作的函數(shù))
● 轉(zhuǎn)換函數(shù)(用來轉(zhuǎn)換數(shù)據(jù)類型和值的函數(shù))
● 聚合函數(shù)(用來進行數(shù)據(jù)聚合的函數(shù))

算術(shù)函數(shù)
-- DDL:創(chuàng)建表
CREATE TABLE SampleMath (m NUMERIC (10,3),
n INTEGER, p INTEGER);

-- DML:插入數(shù)據(jù)
BEGIN TRANSACTION;
postgres=# INSERT INTO SampleMath(m, n, p) VALUES(500, 0, NULL);
INSERT 0 1
postgres=# INSERT INTO SampleMath(m, n, p) VALUES(-180, 0, NULL);
INSERT 0 1
postgres=# INSERT INTO SampleMath(m, n, p) VALUES(NULL, NULL, NULL);
INSERT 0 1
postgres=# INSERT INTO SampleMath(m, n, p) VALUES(NULL, 7, 3);
INSERT 0 1
postgres=# INSERT INTO SampleMath(m, n, p) VALUES(NULL, 5, 2);
INSERT 0 1
postgres=# INSERT INTO SampleMath(m, n, p) VALUES(NULL, 4, NULL);
INSERT 0 1
postgres=# INSERT INTO SampleMath(m, n, p) VALUES(8, NULL, 3);
INSERT 0 1
postgres=# INSERT INTO SampleMath(m, n, p) VALUES(2.27, 1, NULL);
INSERT 0 1
postgres=# INSERT INTO SampleMath(m, n, p) VALUES(5.555, 2, NULL);
INSERT 0 1
postgres=# INSERT INTO SampleMath(m, n, p) VALUES(NULL, 1, NULL);
INSERT 0 1
postgres=# INSERT INTO SampleMath(m, n, p) VALUES(8.76, NULL, NULL);
INSERT 0 1
postgres=# COMMIT;

查看一下該表:


6-1.png
1ABS--絕對值
SELECT m,
postgres-# ABS(m) AS abs_col
postgres-# FROM SampleMath;
6-2.png
2MOD--求余
6-3.png

注意:此處書上代碼少了第一行最后的逗號。
取余只能針對兩個整數(shù)值而言。

3ROUND--四舍五入
6-4.png

ROUND函數(shù)用法:ROUND(對象數(shù)值,保留小數(shù)的位數(shù))

字符串函數(shù)

首先建立表SampleStr

BEGIN TRANSACTION;
BEGIN
postgres=# INSERT INTO SampleStr (str1, str2, str3) VALUES('opx','rx',NULL);
INSERT 0 1
postgres=# INSERT INTO SampleStr (str1, str2, str3) VALUES('abc','def',NULL);
INSERT 0 1
postgres=# INSERT INTO SampleStr (str1, str2, str3) VALUES('山田','太郎','是我');
INSERT 0 1
postgres=# INSERT INTO SampleStr (str1, str2, str3) VALUES('aaa',NULL,NULL);
INSERT 0 1
postgres=# INSERT INTO SampleStr (str1, str2, str3) VALUES(NULL,'xyz',NULL);
INSERT 0 1
postgres=# INSERT INTO SampleStr (str1, str2, str3) VALUES('@&*%$',NULL,NULL);
INSERT 0 1
postgres=# INSERT INTO SampleStr (str1, str2, str3) VALUES('ABC',NULL,NULL);
INSERT 0 1
postgres=# INSERT INTO SampleStr (str1, str2, str3) VALUES('aBC',NULL,NULL);
INSERT 0 1
postgres=# INSERT INTO SampleStr (str1, str2, str3) VALUES('abc太郎','abc','ABC');
INSERT 0 1
postgres=# INSERT INTO SampleStr (str1, str2, str3) VALUES('abcdefabc','abc','ABC');
INSERT 0 1
postgres=# INSERT INTO SampleStr (str1, str2, str3) VALUES('micmic','i','I');
INSERT 0 1
postgres=# COMMIT;

SELECT * FROM SampleStr;

觀察表SampleStr:


6-5.png
1||--拼接
SELECT str1, str2,
        str1 || str2 AS str_concat
   FROM SampleStr;
6-6.png

也可以把三個字符串同時拼接:


6-7.png
2LENGTH--字符串長度
SELECT str1,
       length(str1) AS len_str
  FROM SampleStr;
3LOWER--小寫轉(zhuǎn)換

LOWER函數(shù)只能針對英文字母的情況

SELECT str1,
       LOWER(str1) AS low_str
  FROM SampleStr;
4REPLACE--字符串的替換

REPLACE(str1, str2, str3) AS rep_str:對象字符串str1,需要替換的字符串str2,替換后的字符串str3


6-8.png
5SUBSTRING--字符串的截取

SUBSTRING函數(shù)的語法:
SUBSTRING(對象字符串 FROM 截取的起始位置 FOR 截取的字符數(shù))


6-9.png
6UPPER--大寫轉(zhuǎn)換

UPPER函數(shù)仍然只針對英文字母使用


6-10.png
日期函數(shù)
1CURRENT_DATE--當(dāng)前日期
SELECT CURRENT_DATE;
2CURRENT_TIME--當(dāng)前時間
SELECT CURRENT_TIME;
3EXTRACT--截取日期元素
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;
6-11.png
轉(zhuǎn)換函數(shù)
1CAST--類型轉(zhuǎn)換

將字符串類型轉(zhuǎn)換成數(shù)值類型:


6-12.png

將字符串類型轉(zhuǎn)換成日期類型:


6-13.png
2COALESCE--將NULL轉(zhuǎn)換成其他值
6-14.png

另一個例子,把空值替換為字符串‘NULL’


6-14.png

6-2謂詞

謂詞是函數(shù)的一種,但是它的特點是:返回值一定是真值(TRUE,FALSE,UNKNOWN)

LIKE謂詞--字符串的部分一致查詢

首先我們先創(chuàng)建一個表

--創(chuàng)建SampleLike表
-- DDL:創(chuàng)建表
CREATE TABLE SampleLike
( strcol VARCHAR(6) NOT NULL,
PRIMARY KEY (strcol));
-- DML:插入數(shù)據(jù)
BEGIN 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;

想要從該表中讀取出包含字符串“ddd”的記錄時,可能會得到前方一致、中間一致和后方一致等不同的結(jié)果。

前方一致 :選取出“dddabc”
中間一致 :選取出“abcddd”“dddabc”“abdddc”
后方一致 :選取出“abcddd”

使用LIKE進行前方一致查詢:

SELECT *
  FROM SampleLike
 WHERE strcol LIKE 'ddd%';

使用LIKE進行中間一致查詢:

SELECT * 
  FROM SampleLike
 WHERE strcol LIKE '%ddd%';

使用LIKE進行后方一致查詢:

SELECT *
  FROM SampleLike
 WHERE strcol LIKE '%ddd';

我們還可以使用 _(下劃線)來代替 %,與 % 不同的是,它代表了“任意 1 個字符”

使用LIKE和_(下劃線)進行后方一致查詢:

SELECT *
  FROM SampleLike
 WHERE strcol LIKE 'abc__';   --這里是兩個下劃線
6-15.png

上述代碼只能取出后方有兩個字符的結(jié)果,同樣地,我們也可以查詢出‘a(chǎn)bc+三個字符'的結(jié)果:

SELECT *
FROM SampleLike
WHERE strcol LIKE 'abc___';  --這里是三個下劃線
BETWEEN謂詞--范圍查詢
6-16.png

BETWEEN 的特點就是結(jié)果中會包含 100 和 1000 這兩個臨界值。 如果不想讓結(jié)果中包含臨界值,那就必須使用WHERE:


6-17.png
IS NULL,IS NOT NULL--判斷是否為NULL
6-18.png
IN謂詞--OR的簡便用法

我們需查詢單價為320,500和5000的商品,可以使用OR:


6-19.png

使用IN來簡化:


6-20.png

NOT IN的用法:
6-21.png

但需要注意的是,IN和NOT IN都是無法取出NULL數(shù)據(jù)的,只能用 IS (NOT) NULL。

使用子查詢作為IN謂詞的參數(shù)

我們先建立下面這個表:


6-22.png
 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));
INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES('000A','東京','0001',30);
INSERT 0 1
postgres=# INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES('000A','東京','0002',50);
INSERT 0 1
postgres=# INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES('000A','東京','0003',15);
INSERT 0 1
postgres=# INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES('000B','名古屋','0002',30);
INSERT 0 1
postgres=# INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES('000B','名古屋','0003',120);
INSERT 0 1
postgres=# INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES('000B','名古屋','0004',20);
INSERT 0 1
postgres=# INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES('000B','名古屋','0006',10);
INSERT 0 1
postgres=# INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES('000B','名古屋','0007',40);
INSERT 0 1
postgres=# INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES('000C','大阪','0003',20);
INSERT 0 1
postgres=# INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES('000C','大阪','0004',50);
INSERT 0 1
postgres=# INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES('000C','大阪','0006',90);
INSERT 0 1
postgres=# INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES('000C','大阪','0007',70);
INSERT 0 1
postgres=# INSERT INTO ShopProduct (shop_id, shop_name, product_id, quantity) VALUES('000D','福岡','0001',100);
INSERT 0 1

我們希望讀取的是大阪店在售商品的商品名稱及銷售單價:


6-23.png

NOT IN也可以用在子查詢中:


6-23.png
EXIST謂詞

謂詞的作用就是“判斷是否存在滿足某種條件的記錄”。如果存在這樣的記錄就返回真(TRUE),如果不存在就返回假(FALSE)。 EXIST(存在)謂詞的主語是“記錄”。
使用 EXIST 選取出大阪店在售商品的銷售單價:


6-24.png

由于 EXIST 只關(guān)心記錄是否存在,因此返回哪些列都沒有關(guān)系。即使寫成下列代碼那樣,結(jié)果也不會發(fā)生改變。可以把在 EXIST 的子查詢中書寫 SELECT * 當(dāng)作 SQL 的一種習(xí)慣。

SELECT product_name, sale_price 
  FROM Product AS P
 WHERE EXISTS (SELECT 1--此處為任意常數(shù)
                 FROM ShopProduct AS SP
                WHERE SP.shop_id = '000C'
                  AND SP.product_id = P.product_id);

同樣可以使用NOT EXIST代替NOT IN,使用NOT EXIST讀取出“東京店在售之外的商品的銷售單價”:


6-25.png

6-3CASE表達式

什么是CASE表達式

CASE 表達式是在區(qū)分情況時使用的,這種情況的區(qū)分在編程中通常稱為(條件)分支。

CASE表達式的使用方法

對于Product表,我們希望得到如下結(jié)果:


6-26.png
---使用搜索CASE表達式的寫法--
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;
6-27.png

ELSE子句也可以省略不寫,這時會被默認為ELSE NULL。此外,CASE 表達式最后的“END”是不能省略的,請大家特別注意不要遺漏。
可以利用 CASE 表達式將下述 SELECT 語句結(jié)果中的行和列進行互換。

SELECT product_type,
       SUM(sale_price) AS sum_price,
  FROM Product
 GROUP BY product_type;
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;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容