與很多編程語言一樣葛闷,SQL 也支持函數(shù)嫩絮,為數(shù)據(jù)的轉(zhuǎn)換和處理提供了方法迷雪,比如前面我們用到的 RTRIM
函數(shù)去掉文本右側(cè)可能存在的空白字符碘勉。
注:對于不同的 DBMS 各個函數(shù)的名稱和用法可能及其不同板辽,只有很少的函數(shù)被所有主要的 DBMS 支持。本篇文章使用的演示 DBMS 為 SQLite棘催,練習(xí)前請使用
SELECT
語句檢測你的環(huán)境是否支持相關(guān)函數(shù)劲弦。
今天,我們主要學(xué)習(xí)兩類常用的函數(shù):文本處理函數(shù)和日期巧鸭、時(shí)間函數(shù)瓶您。
文本處理函數(shù)
前面我們提到的 RTRIM
LTRIM
TRIM
都是非常常見的文本處理函數(shù)。下面是小魚總結(jié)的 SQL 常用文本處理函數(shù)纲仍。
函數(shù) | 說明 |
---|---|
LEFT() / RIGHT() | 返回字符串左邊 / 右邊的字符。 |
LENGTH() / DATALENGTH() / LEN() | 返回字符串的長度贸毕。 |
LOWER() / UPPER() | 將字符串轉(zhuǎn)換為小寫 / 大寫郑叠。 |
LTRIM() / RTRIM() / TRIM() | 去掉字符串左邊 / 右邊 / 兩邊的空格。 |
SUBSTR() / SUBSTRING() | 提取子字符串 |
下面明棍,小魚先演示一下 UPPER
函數(shù)的使用乡革。從供應(yīng)商表中檢索出供應(yīng)商名稱以及供應(yīng)商名稱的大寫形式,并將大寫的列命名為 vend_name_upcase
摊腋。
SELECT
vend_name,
UPPER( vend_name ) AS vend_name_upcase
FROM
Vendors
ORDER BY
vend_name;
檢索結(jié)果:
UPPER
函數(shù)將供應(yīng)商的名稱轉(zhuǎn)換為了大寫形式沸版。
下面,小魚再來舉個文本函數(shù)的例子兴蒸。字符串截取函數(shù) SUBSTR
SUBSTRING
视粮,使用 SELECT
語句來檢測一下 SQLite
是否支持 SUBSTR
函數(shù)。
SELECT
SUBSTR( 'abcdef', 1, 2 ),
SUBSTR( 'abcdef', 1, 3 ),
SUBSTR( 'abcdef', 3 );
上述 SQL 沒有報(bào)錯橙凳,并返回了如下的結(jié)果:
第一個參數(shù) abcdef
表示待截取的文本蕾殴,第二個參數(shù)為從第幾個字符開始截取,最后一個參數(shù)為截取多少位岛啸。最后一個參數(shù)省略時(shí)將截取之后的所有長度钓觉。
然后,我們使用 SUBSTR
函數(shù)從 cust_contact
中取取前 2 個字符坚踩,從 cust_city
中提取 3 個字符荡灾,將他們轉(zhuǎn)換為大寫形式,并拼接在一起瞬铸,以 user_login
別名返回批幌。
客戶信息表如下:
編寫 SQL 檢索出客戶 ID 、客戶名稱以及登錄名 user_login
:
SELECT
cust_id,
cust_name,
UPPER(
SUBSTR( cust_contact, 1, 2 ) || SUBSTR( cust_city, 1, 3 )) AS user_login
FROM
Customers;
檢索結(jié)果:
日期赴捞、時(shí)間處理函數(shù)
日期逼裆、時(shí)間類型作為特殊的類型存儲在表中,每種 DBMS 都以各自的特殊形式進(jìn)行存儲赦政,以便進(jìn)行快速胜宇、有效的排序或過濾耀怜,并且占用更少的空間存儲。
我們需要借助日期桐愉、時(shí)間函數(shù)來讀取财破、統(tǒng)計(jì)和處理這些日期、時(shí)間从诲,因此日期左痢、時(shí)間函數(shù)在 SQL 中有著非常重要的作用。不過系洛,感到遺憾的是俊性,不同的 DBMS 這些日期時(shí)間函數(shù)相差很大,可移植性最差描扯。
比如定页,可以使用如下語句檢測一下你的數(shù)據(jù)庫是否支持使用 CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
來獲取當(dāng)前日期、時(shí)間绽诚、日期時(shí)間典徊。
SELECT
CURRENT_DATE,
CURRENT_TIME,
CURRENT_TIMESTAMP;
下面是小魚的 SQLite 數(shù)據(jù)庫返回的結(jié)果:
使用 STRFTIME
可以將表中的日期時(shí)間類型轉(zhuǎn)換為指定格式的日期時(shí)間字符串。在不支持使用 YEAR
DATEPART
和 EXTRACT
函數(shù)的 DBMS 中恩够,還可以用 STRFTIME
提取年卒落、月等日期時(shí)間的成分。
SELECT
STRFTIME( '%Y/%m/%d %H:%M:%S', CURRENT_TIMESTAMP ),
STRFTIME( '%Y', CURRENT_TIMESTAMP ),
STRFTIME( '%m', CURRENT_TIMESTAMP );
下面是小魚的 SQLite 數(shù)據(jù)庫返回的結(jié)果:
函數(shù) DATETIME
DATE
可以將日期時(shí)間格式的字符串轉(zhuǎn)換為表中的日期時(shí)間類型蜂桶,以便進(jìn)行過濾和運(yùn)算秒紧。
SELECT
DATETIME( '2022-03-13 05:44:19' ),
DATE('2022-03-13');
下面是小魚的 SOLite 數(shù)據(jù)庫 DATE
DATETIME
返回結(jié)果约炎。
最后副女,我們來看幾個案例个粱,案例使用的表格為下面的訂單表:
首先,我們需要檢索出 2020 年 2 月份的所有訂單編號和訂單日期:
SELECT
order_num,
order_date
FROM
Orders
WHERE
STRFTIME( '%Y/%m', order_date ) = '2020/02';
上述 SQL 語句中钦购,將表中的日期類型 order_date
日期轉(zhuǎn)換為 %Y/%m
格式的日期字符串檐盟,然后利用字符串的比較來篩選出 2020 年 02 月份的訂單。檢索結(jié)果如下:
前面押桃,小魚說表中存儲的日期時(shí)間類型可以很方便地進(jìn)行排序和過濾葵萎。下面我們就先來看看過濾吧!使用 SQL 語句篩選出 2020 年 1 月 15 號至 2020 年 2 月 15 號的所有訂單:
SELECT
order_num,
order_date
FROM
Orders
WHERE
order_date BETWEEN DATE( '2020-01-15' )
AND DATE( '2020-02-15' );
使用 DATE()
函數(shù)可以將時(shí)間格式的字符串轉(zhuǎn)換為表中的日期類型唱凯,日期類型同樣可以用于比較操作符和 BETWEEN
等羡忘。檢索結(jié)果如下:
日期時(shí)間類型也可以用于排序的依據(jù):
SELECT
order_num,
order_date
FROM
Orders
WHERE
STRFTIME( '%Y%m', order_date ) = '202001'
ORDER BY
order_date;
按升序方式返回的 2020 年 1 月份訂單:
總結(jié)
本節(jié),我們主要學(xué)習(xí)了 SQL 中常用的文本處理函數(shù)以及時(shí)間磕昼、日期處理函數(shù)卷雕。這些函數(shù)在格式化、數(shù)據(jù)過濾等方面非常重要票从,但比較遺憾的是它們在不同的 DBMS 中實(shí)現(xiàn)很不一致漫雕,可移植性差滨嘱。