SQL 語句中的函數(shù)

與很多編程語言一樣葛闷,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 DATEPARTEXTRACT 函數(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)很不一致漫雕,可移植性差滨嘱。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市浸间,隨后出現(xiàn)的幾起案子太雨,更是在濱河造成了極大的恐慌,老刑警劉巖魁蒜,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件囊扳,死亡現(xiàn)場離奇詭異,居然都是意外死亡兜看,警方通過查閱死者的電腦和手機(jī)锥咸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來铣减,“玉大人她君,你說我怎么就攤上這事『” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵球涛,是天一觀的道長劣针。 經(jīng)常有香客問我,道長亿扁,這世上最難降的妖魔是什么捺典? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮从祝,結(jié)果婚禮上襟己,老公的妹妹穿的比我還像新娘。我一直安慰自己牍陌,他們只是感情好擎浴,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著毒涧,像睡著了一般贮预。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上契讲,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天仿吞,我揣著相機(jī)與錄音,去河邊找鬼捡偏。 笑死唤冈,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的银伟。 我是一名探鬼主播你虹,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼绘搞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了售葡?” 一聲冷哼從身側(cè)響起看杭,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎挟伙,沒想到半個月后楼雹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡尖阔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年贮缅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片介却。...
    茶點(diǎn)故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡谴供,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出齿坷,到底是詐尸還是另有隱情桂肌,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布永淌,位于F島的核電站崎场,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏遂蛀。R本人自食惡果不足惜谭跨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望李滴。 院中可真熱鬧螃宙,春花似錦、人聲如沸所坯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽包竹。三九已至燕酷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間周瞎,已是汗流浹背苗缩。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留声诸,地道東北人酱讶。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像彼乌,于是被迫代替她去往敵國和親泻肯。 傳聞我的和親對象是個殘疾皇子渊迁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容