SQL 函數
1. 定義
慕課解釋:
函數
可以把經常使用的代碼封裝起來,以便需要的時候直接調用。
本小節,我們將一起學習 SQL 函數。
2. 前言
我們在學習編程語言時候,也會遇到函數,在 SQL 中也是如此,如果你熟悉 Python 或者其它語言,那么一定使用過print
這個內置函數。SQL 為了給開發者提供便利,也提供了一系例的內置函數,它們大致可分為算術函數
、字符串函數
、日期函數
、轉換函數
和聚合函數
五大類。
SQL 除了提供好用的內置函數外,還可以通過 Create 指令來新建一個自定義函數。在這個小節中,我們會簡單的介紹自定義函數的創建和使用,而內置函數我們將在后面的幾個小節中詳細介紹。
本小節測試數據如下,請先在數據庫中執行:
DROP TABLE IF EXISTS imooc_user;
CREATE TABLE imooc_user
(
id int PRIMARY KEY,
username varchar(20),
age int
);
INSERT INTO imooc_user(id,username,age)
VALUES (1,'peter',18),(2,'pedro',24),(3,'jerry',22),(4,'mike',18),(5,'tom',20);
3. 語法
SQL 函數是一組 SQL 語句的封裝,因此它的創建是頗為復雜的,大致的步驟可概括為如下幾步:
- 通過
CREATE FUNCTION [function_name]
來聲明一個函數。如:CREATE FUNCTION getUsername; - 在函數名中通過變量聲明函數參數,如
getUsername(uid int)
,并通過returns
指定返回值類型,如 returns varchar,表示函數返回字符串類型; - 通過
BEGIN
開始函數體,并通過END
來結束函數體; - 若在函數體內使用了變量,需通過
DECLARE
來聲明變量,如 DECLARE uname varchar(20); - 在函數體內使用 SQL 語句得到結果,并通過
RETURN
指定返回值。
我們通過上述步驟新建一個 getUsername 函數,該函數通過用戶 id 獲取用戶名。
CREATE FUNCTION getUsername(uid int) RETURNS varchar(20)
BEGIN
DECLARE uname varchar(20);
SELECT username FROM imooc_user WHERE id = uid INTO uname;
RETURN uname;
END;
在 getUsername 函數體中,若要給 uname 這樣的局部變量賦值,需要使用INTO
關鍵字。函數創建完畢后,通過 Select 來調用,如SELECT getUsername(1)
。
結果如下:
# SELECT getUsername(1);
+----------------+
| getUsername(1) |
+----------------+
| pedro |
+----------------+
4. 實踐
4.1 例1 獲得最大年齡
請書寫 SQL 語句,新建一個getOldestAge
函數,該函數獲得imooc_user
中用戶的最大年齡。
分析:
按照上面步驟新建函數 getOldestAge,且該函數無參,但返回類型為 int ,最大年齡我們可以先使用 Order By 對其排序,然后通過Limit 取第一位用戶,則可得到最大的年齡。
語句:
整理可得語句如下:
CREATE FUNCTION getOldestAge() RETURNS int
BEGIN
RETURN (SELECT age FROM imooc_user ORDER BY age DESC LIMIT 1);
END;
創建該函數后,使用 Select 來調用:
SELECT getOldestAge();
結果如下:
+----------------+
| getOldestAge() |
+----------------+
| 23 |
+----------------+
5. 小結
SQL 自定義函數是十分復雜的一環,難學且使用少,我們不推薦你在自定義函數上死磕。在這個小節里,我們沒有介紹 PostgreSQL 自定義函數的使用,因為在 PostgreSQL 中,自定義函數更加復雜。在市面上,我們很少看到書籍和資料會花大量篇幅在自定義函數上,但是如果你感興趣,我們可以給你推薦幾個鏈接。
- 在查詢的時候,尤其是在 Where 的條件中
慎用函數
,它會導致查詢不走索引,從而拉低查詢的速度。 - 自定義函數用的
非常少
,因為它的移植性很差,取得的效果也不明顯。