SQL 字符函數(shù)用于字符數(shù)據(jù)的處理,例如字符串的拼接、大小寫轉(zhuǎn)換、子串的查找和替換等。
本文比較五種主流數(shù)據(jù)庫常用字符函數(shù)的實現(xiàn)和差異,包括 MySQL、Oracle、SQL Server、PostgreSQL 以及 SQLite。
字符函數(shù) | 函數(shù)功能 | MySQL | Oracle | SQL Server | PostgreSQL | SQLite |
---|
CHAR_LENGTH(s) | 返回字符串s包含的字符數(shù)量 | ✔️ | LENGTH(s) | LEN(s) | ✔️ | LENGTH(s) |
CONCAT(s1, s2, …) | 連接字符串 | ✔️ | ✔️ | ✔️ | ✔️ | || |
INSTR(s, s1) | 返回子串首次出現(xiàn)的位置 | ✔️ | ✔️ | PATINDEX(s1, s) | POSITION(s1 IN s) | ✔️ |
LOWER(s) | 返回字符串s的小寫形式 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
OCTET_LENGTH(s) | 返回字符串s包含的字節(jié)數(shù)量 | ✔️ | LENGTHB(s) | DATALENGTH(s) | ✔️ | ❌ |
REPLACE(s, old, new) | 將字符串中的old替換為new | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
SUBSTRING(s, n, m) | 返回從位置n開始的m個字符 | ✔️ | SUBSTR(s, n, m) | ✔️ | ✔️ | ✔️ |
TRIM(s1 FROM s) | 刪除字符串開頭和結(jié)尾的子串 | ✔️ | ✔️ | ✔️ | ✔️ | TRIM(s, s1) |
UPPER(s) | 返回字符串s的大寫形式 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
下面我們通過一些示例來說明這些函數(shù)的作用和注意事項。
字符串的長度
字符串的長度可以按照兩種方式進行計算:字符數(shù)量和字節(jié)數(shù)量。在多字節(jié)編碼中,一個字符可能占用多個字節(jié)。
CHAR_LENGTH(s) 函數(shù)用于計算字符串中的字符數(shù)量,OCTET_LENGTH(s) 函數(shù)用于計算字符串包含的字節(jié)數(shù)量。例如:
-- MySQL 和 PostgreSQL
SELECT CHAR_LENGTH('數(shù)據(jù)庫'), OCTET_LENGTH('數(shù)據(jù)庫');
查詢返回的結(jié)果如下:
CHAR_LENGTH('數(shù)據(jù)庫')|OCTET_LENGTH('數(shù)據(jù)庫')
--------------------|---------------------
3| 9
字符串“數(shù)據(jù)庫”包含 3 個字符,在 UTF-8 編碼中占用 9 個字節(jié)。MySQL 和 PostgreSQL 實現(xiàn)了這兩個標準函數(shù)。
Oracle 使用 LENGTH(s) 函數(shù)和 LENGTHB 函數(shù)計算字符數(shù)量和字節(jié)數(shù)量,例如:
-- Oracle
SELECT LENGTH('數(shù)據(jù)庫'), LENGTHB('數(shù)據(jù)庫')
FROM dual;
查詢返回的結(jié)果和上面的示例相同。
提示:PostgreSQL 也提供了 LENGTH(s) 函數(shù),用于返回字符串中的字符數(shù)量。MySQL 也提供了 LENGTH(s) 函數(shù),用于返回字符串中的字節(jié)數(shù)量。
Microsoft SQL Server 使用 LEN(s) 函數(shù)和 DATALENGTH(s) 函數(shù)計算字符數(shù)量和字節(jié)數(shù)量,例如:
-- SQL Server
SELECT LEN('數(shù)據(jù)庫'), DATALENGTH('數(shù)據(jù)庫');
查詢返回的結(jié)果如下:
LEN|DATALENGTH
---|----------
3| 6
字符串“數(shù)據(jù)庫”在“Chinese_PRC_CI_AS”字符集中占用 6 個字節(jié),每個漢字占用 2 個字節(jié)。
SQLite 只提供了 LENGTH(s) 函數(shù),用于計算字符串中的字符個數(shù),例如:
-- SQLite
SELECT LENGTH('數(shù)據(jù)庫');
查詢返回的結(jié)果如下:
LENGTH('數(shù)據(jù)庫')
--------------
3
連接字符串
CONCAT(s1, s2, …) 函數(shù)將兩個或者多個字符串連接到一起,組成一個新的字符串。例如:
-- MySQL、Microsoft SQL Server 以及 PostgreSQL
SELECT CONCAT('S', 'Q', 'L');
查詢返回的結(jié)果如下:
CONCAT('S', 'Q', 'L')
---------------------
SQL
Oracle 中的 CONCAT 函數(shù)一次只能連接兩個字符串,例如:
SELECT CONCAT(CONCAT('S', 'Q'), 'L')
FROM dual;
我們通過嵌套函數(shù)調(diào)用連接多個字符串,查詢返回的結(jié)果和上面的示例相同。
SQLite 沒有提供連接字符串的函數(shù),可以通過連接運算符(||)實現(xiàn)字符串的連接。例如:
-- SQLite、Oracle 以及 PostgreSQL
SELECT 'S' || 'Q' || 'L';
查詢返回的結(jié)果和上面的示例相同。
提示:Oracle 和 PostgreSQL 也提供了連接運算符(||),Microsoft SQL Server 使用加號(+)作為連接運算符。
除 CONCAT 函數(shù)外,還有一個 CONCAT_WS(separator, s1, s2 , … ) 函數(shù),可以使用指定分隔符連接字符串。例如:
-- MySQL、Microsoft SQL Server 以及 PostgreSQL
SELECT CONCAT_WS('-','S', 'Q', 'L');
查詢返回的結(jié)果如下。
CONCAT_WS('-','S', 'Q', 'L')
----------------------------
S-Q-L
MySQL、Microsoft SQL Server 以及 PostgreSQL 實現(xiàn)了該函數(shù)。
大小寫轉(zhuǎn)換
LOWER(s) 函數(shù)將字符串轉(zhuǎn)換為小寫形式,UPPER(s) 函數(shù)將字符串轉(zhuǎn)換為大寫形式。例如:
SELECT LOWER('SQL'), UPPER('sql')
FROM employee
WHERE emp_id = 1;
查詢返回的結(jié)果如下:
LOWER('SQL')|UPPER('sql')
------------|------------
sql |SQL
提示:MySQL 中的 LCASE 函數(shù)等價于 LOWER 函數(shù),UCASE 函數(shù)等價于 UPPER 函數(shù)。Oracle 和 PostgreSQL 還提供了首字母大寫的 INITCAP 函數(shù)。
獲取子串
SUBSTRING(s, n, m) 函數(shù)返回字符串 s 中從位置 n 開始的 m 個字符子串。例如:
-- MySQL、Microsoft SQL Server、PostgreSQL 以及 SQlite
SELECT SUBSTRING('數(shù)據(jù)庫', 1, 2);
查詢返回的結(jié)果如下:
SUBSTRING('數(shù)據(jù)庫', 1, 2)
-----------------------
數(shù)據(jù)
Oracle 使用簡寫的 SUBSTR(s, n, m) 函數(shù)返回子串,例如:
-- Oracle、MySQL、PostgreSQL 以及 SQLite
SELECT SUBSTR('數(shù)據(jù)庫', 1, 2)
FROM dual;
MySQL、PostgreSQL 以及 SQLite 也支持 SUBSTR 函數(shù)。查詢結(jié)果和上面的示例相同。
另外,Oracle、MySQL 以及 SQLite 中的起始位置 n 可以指定負數(shù),表示從字符串的尾部倒數(shù)查找起始位置,然后再返回子串。例如:
-- Oracle、MySQL 以及 SQLite
SELECT SUBSTR('數(shù)據(jù)庫', -2, 2)
FROM employee
WHERE emp_id = 1;
查詢返回的結(jié)果如下。
SUBSTR('數(shù)據(jù)庫', -2, 2)
---------------------
據(jù)庫
其中,-2 表示從右往左數(shù)第 2 個字符(“據(jù)”),然后再返回 2 個字符。
提示:MySQL、Microsoft SQL Server 以及 PostgreSQL 提供了 LEFT(s, n) 和 RIGHT(s, n) 函數(shù),分別用于返回字符串開頭和結(jié)尾的 n 個字符。
子串查找與替換
INSTR(s, s1) 函數(shù)查找并返回字符串 s 中子串 s1 第一次出現(xiàn)的位置。如果沒有找到子串,則會返回 0。例如:
-- Oracle、MySQL 以及 SQLite
SELECT email, INSTR(email, '@')
FROM employee
WHERE emp_id = 1;
查詢返回的結(jié)果如下:
email |INSTR(email, '@')
-----------------|-----------------
liubei@shuguo.com| 7
“@”是字符串“l(fā)iubei@shuguo.com”中的第 7 個字符。
Microsoft SQL Server 使用 PATINDEX(s1, s) 函數(shù)查找子串的位置,例如:
-- Microsoft SQL Server
SELECT email, PATINDEX('%@%', email)
FROM employee
WHERE emp_id = 1;
其中,s1 參數(shù)的形式為 %pattern%,類似于 LIKE 運算符中的匹配模式。查詢返回的結(jié)果和上面的示例相同。
PostgreSQL 使用 POSITION (s1 IN s) 函數(shù)查找子串的位置,例如:
-- PostgreSQL
SELECT email, POSITION('@' IN email)
FROM employee
WHERE emp_id = 1;
查詢返回的結(jié)果和上面的示例相同。
REPLACE(s, old, new) 函數(shù)將字符串 s 中的子串 old 替換為 new。例如:
SELECT email, REPLACE(email, 'com', 'net')
FROM employee
WHERE emp_id = 1;
查詢返回的結(jié)果如下:
email |REPLACE(email, 'com', 'net')
-----------------|----------------------------
liubei@shuguo.com|liubei@shuguo.net
REPLACE 函數(shù)在 5 種主流數(shù)據(jù)庫中的實現(xiàn)一致。
截斷字符串
TRIM(s1 FROM s) 函數(shù)刪除字符串 s 開頭和結(jié)尾的子串 s1。例如:
-- Oracle、MySQL、Microsoft SQL Server 以及 PostgreSQL
SELECT TRIM('-' FROM '--S-Q-L--'), TRIM(' S-Q-L ')
FROM employee
WHERE emp_id = 1;
第一個函數(shù)刪除了開頭和結(jié)尾的“-”;第二個函數(shù)省略了 s1 子串,默認表示刪除開頭和
結(jié)尾的空格。查詢返回的結(jié)果如下:
TRIM('-' FROM '--S-Q-L--')|TRIM(' S-Q-L ')
--------------------------|-----------------
S-Q-L |S-Q-L
Oracle 中的參數(shù) s1 只能是單個字符,其他數(shù)據(jù)庫中的參數(shù) s1 可以是多個字符。
SQLite 中的 TRIM(s, s1) 函數(shù)的調(diào)用格式與其他數(shù)據(jù)庫不同,例如:
-- SQLite
SELECT TRIM('--S-Q-L--', '-'), TRIM(' S-Q-L ');
查詢返回的結(jié)果和上面的示例相同。
提示:LTRIM(s)函數(shù)可以刪除字符串開頭的空格,RTRIM(s)函數(shù)可以刪除字符串尾部的空格,這兩個函數(shù)是 TRIM 函數(shù)的簡化版。
該文章在 2024/3/15 14:56:27 編輯過