四、SQL函数②(字符串函数)

字符串函数:用户的密码、电子邮箱地址、证件号码等都是以字符串类型保存在数据库中的。

计算字符串长度

LENGTH()函数用来计算一个字符串的长度。该函数接受一个参数,此参数为待计算的字符串表达式,在MYSQLServer 中这个函数名称为LEN()。

MYSQL,Oracle,DB2:
SELECT FName, LENGTH(FName) FROM T_Person
MSSQLServer:
SELECT FName, LEN(FName) FROM T_Person

字符串转换为小写

LOWER()函数用来将一个字符串转换为小写。该函数接受一个参数,此参数为待转换的字符串表达式,在DB2 中这个函数名称为LCASE()。如下SQL语句:

MYSQL,MSSQLServer,Oracle:
SELECT FName, LOWER(FName) FROM T_Person
SELECT FName, LCASE(FName) FROM T_Person

字符串转换为大写

UPPER()函数用来将一个字符串转换为大写。该函数接受一个参数,此参数为待转换的字符串表达式,在DB2中这个函数名称为UCASE ()。如下面SQL语句:

MYSQL,MSSQLServer,Oracle:
SELECT FName, UPPER(FName) FROM T_Person
SELECT FName, UCASE(FName) FROM T_Person

截去字符串左侧空格

LTRIM()函数用来将一个字符串左侧的空格去掉。该函数接受一个参数,此参数为待处理的字符串表达式。如下的SQL语句:

SELECT FName,LTRIM(FName),LTRIM("abc") FROM T_Person

截去字符串右侧空格

RTRIM ()函数用来将一个字符串左侧的空格去掉。该函数接受一个参数,此参数为待处理的字符串表达式。如下的SQL语句:

SELECT FName,RTRIM(FName),RTRIM("abc") FROM T_Person

截去字符串两侧的空格

TRIM ()函数用来将一个字符串两侧的空格去掉。该函数接受一个参数,此参数为待处理的字符串表达式。此函数只在MYSQL 和Oracle 中提供支持,在MSSQLServer和DB2中可以使用LTRIM()函数和RTRIM()函数复合来进行变通实现,也就是用LTRIM(RTRIM(string))来模拟实现TRIM (string)。

MYSQL,Oracle:
SELECT FName,TRIM(FName),TRIM(" abc ") FROM T_Person
MSSQLServer,DB2:
SELECT FName,LTRIM(RTRIM(FName)),LTRIM(RTRIM(" abc ")) FROM T_Person

取子字符串

字符串是由多个字符组成的串,比如“HelloWorld”在内存是如下存储的:

1 2 3 4 5 6 7 8 9 10
H e l l o W o r l d

表格第一行的数字表示组成字符串的每个字符的位置,第二行则为各个位置上的字符。由这些字符中连续的多个字符还可以组成新的字符串,新的字符串则被称为“子字符串”。
如:从第3 个字符到第5 个字符组成的“llo”就是一个子字符串,我们也可以称“llo”为从第3 个字符开始长度为3 的子字符串。

计算子字符串的函数SUBSTRING(),其参数格式如下:

SUBSTRING(string,start_position,length)

其中参数string为主字符串,start_position为子字符串在主字符串中的起始位置,length为子字符串的最大长度。
在MYSQL和MSSQLServer 中支持这个函数,在Oracle和DB2中这个函数的名称为SUBSTR()
如下的SQL语句:

MYSQL、MSSQLServer:
SELECT SUBSTRING("abcdef111",2,3)
Oracle:
SELECT SUBSTR("abcdef111",2,3) FROM DUAL
SELECT SUBSTR("abcdef111",2,3) FROM SYSIBM.SYSDUMMY1

执行结果:

SUBSTRING("abcdef111",2,3)

再如下的SQL语句:

MYSQL,MSSQLServer:
SELECT FName, SUBSTRING(FName,2,3) FROM T_Person
Oracle,DB2:
SELECT FName, SUBSTR(FName,2,3) FROM T_Person

执行结果:

FName SUBSTRING(FName,2,3)
Tom om
Jim im
Lily ily
Kelly ell
Sam am
Kerry err
Smith mit
BillGates ill

计算子字符串的位置

用于检测制定的子字符串是否存在于主字符串中,如果存在则还可以返回所在的位置。该函数在MYSQL 和Oracle中名称为INSTR,其参数格式如下:

INSTR(string,substring)

其中参数string为主字符串,参数substring为待查询的子字符串。如果string中存在substring子字符串,则返回子字符串第一个字符在主字符串中出现的位置;如果string中不存在substring子字符串,则返回0。

在MSSQLServer中这个函数名为CHARINDEX,其参数格式以及返回值规则与MYSQL以及Oracle一致。

在DB2中这个函数名为LOCATE,其返回值规则与前述几种数据库系统一致,不过参数格式与它们正好相反,其参数格式如下:

LOCATE(substring,string)

其中参数substring为待查询的子字符串,参数string为主字符串,也就是两个参数的位置是与其它集中数据库系统相反的。如下的SQL语句:

MYSQL,Oracle:
SELECT FName, INSTR(FName,"m") , INSTR(FName,"ly") FROM T_Person
MSSQLServer:
SELECT FName,CHARINDEX(FName,"m"), CHARINDEX(FName,"ly") FROM T_Person
SELECT FName, LOCATE("m",FName) , LOCATE("ly",FName) FROT_Person

从左侧开始取子字符串

使用SUBSTRING()函数:从任意位置开始取任意长度的子字符串,不过有的时候我们只需要从左侧开始取子字符串,这样指定主字符串和要取的长度就可以了,不过如果使用SUBSTRING()函数的话仍然需要指定三个参数,其中第二个参数为常量1。MYSQL、MSSQLServer、DB2 中提供了LEFT()函数用于从左侧开始取任意长度的子字符串,其参数格式如下:

LEFT (string,length)

其中参数string为主字符串,length为子字符串的最大长度。

Oracle 不支持LEFT()函数,但能使用SUBSTR()函数进行变通实现,即:SUBSTR(string, 1, length)。

如下的SQL语句:

MYSQL,MSSQLServer,DB2:
SELECT FName, LEFT(FName,3) , LEFT(FName,2) FROM T_Person
Oracle:
SELECT FName,SUBSTR(FName, 1,3),SUBSTR(FName, 1,2) FROM T_Person

从右侧开始取子字符串

SUBSTRING()函数:从任意位置开始取任意长度的子字符串,不过有的时候我们只需要从右侧开始取子字符串,这样指定主字符串和要取的长度就可以了,不过如果使用SUBSTRING()函数的话仍然需要指定三个参数。
MYSQL、MSSQLServer、DB2 中提供了RIGHT ()函数:用于从左侧开始取任意长度的子字符串,其参数格式如下:

RIGHT (string,length)

其中参数string为主字符串,length为子字符串的最大长度。

Oracle中不支持RIGHT ()函数,只能使用SUBSTR()函数进行变通实现,其中起始位置用如下表达式计算出来:startposition= LENGTH(string)- length+1
注:SUBSTR(string, LENGTH(string)- length+1, length)等价于RIGHT (string,length)。

执行下面的SQL语句:

MYSQL,MSSQLServer,DB2:
SELECT FName, RIGHT(FName,3) , RIGHT(FName,2) FROM T_Person
Oracle:
SELECT FName,SUBSTR(FName, LENGTH(FName)-3 +1, 3),SUBSTR(FName, LENGTH(FName)-2 +1, 2) FROM T_Person

字符串替换

REPLACE()函数:用来将字符串的指定的子字符串替换为其它的字符串。
将“Hello World”中的“rl”替换为“ok”后得到“Hello Wookd”
把“Just so so”中的“s”替换为“z”后得到“Juzt zo zo”

REPLACE()函数的参数格式如下:

REPLACE(string,string_tobe_replace,string_to_replace)

其中参数string为要进行替换操作的主字符串,参数string_tobe_replace为要被替换的字符串,而string_to_replace将替换string_tobe_replace中所有出现的地方。如下的SQL语句:

select FName,REPLACE(FName,"i","e"),
FIDNumber,REPLACE(FIDNumber,"2345","abcd") FROM T_Person

SQL中没提供删除字符串中匹配的子字符串的方法,但使用REPLACE()函数就可以达到删除子字符串的方法,即:将第三个参数设定为空字符串,用空字符串来替换匹配的子字符串,就能达到了删除指定子字符串的效果
如:将FName中的m以及FIDNumber 中的123 删除

SELECT FName, REPLACE(FName,"m","") ,FIDNumber,
REPLACE(FIDNumber,"123","") FROM T_Person

LTRIM()、RTRIM()和TRIM()都只能删除两侧的字符串,无法删除字符串中间的空格,而使用REPLACE()函数也可以完成这个功能,也就是用空字符串替换中所有的空格。执行下面的SQL语句:

MYSQL、MSSQLServer:
SELECT REPLACE(" abc 123 wpf"," ",""),REPLACE(" ccw enet wcf f"," ","")
Oracle:
SELECT REPLACE(" abc 123 wpf"," ",""),REPLACE(" ccw enet wcf f"," ","") FROM DUAL
SELECT REPLACE(" abc 123 wpf"," ",""),REPLACE(" ccw enet wcf f"," ","") FROM SYSIBM.SYSDUMMY1

得到字符的ASCII码

ASCII()函数用来得到一个字符的ASCII码,它有且只有一个参数,该参数为待求ASCII码的字符,若参数为一个字符串则函数返回第一个字符的ASCII码,如:

MYSQL,MSSQLServer:
SELECT ASCII("a") , ASCII("abc")
Oracle:
SELECT ASCII("a") , ASCII("abc") FROM DUAL
SELECT ASCII("a") , ASCII("abc") FROM SYSIBM.SYSDUMMY1

执行结果:

ASCII("a") ASCII("abc")
97 97

再如:计算每个员工姓名的第一个字符的ASCII码:

MYSQL,MSSQLServer,DB2:
SELECT FName, LEFT(FName,1),ASCII(LEFT(FName,1)),
ASCII(FName) FROM T_Person
Oracle:
SELECT FName,SUBSTR(FName,1,1),
ASCII(SUBSTR(FName, 1,1)),ASCII(FName) FROM T_Person

得到一个ASCII码数字对应的字符

与 ASCII()函数正好相反,该函数用来得到一个字符的ASCII 码的函数。
在MYSQL、MSSQLServer 和DB2 中该函数为:CHAR(),在Oracle中该函数的名字则为CHR()

执行下面的SQL语句:

MYSQL,MSSQLServer:
SELECT CHAR(56),CHAR(90),"a",CHAR(ASCII("a"))
Oracle:
SELECT CHR(56),CHR(90),"a",CHR(ASCII("a")) FROM DUAL
SELECT CHR(56),CHR(90),"a",CHR( ASCII("a")) FROM SYSIBM.SYSDUMMY1

执行结果:

CHAR(56) CHAR(90) a CHAR( ASCII("a") )
8 Z a a

如:将FWeight转换为整数,得到它对应的字符:

MYSQL、MSSQLServer:
SELECT FWeight, CEILING(FWeight),CHAR( CEILING(FWeight) ) FROM T_Person
Oracle:
SELECT FWeight, CEIL(FWeight),CHAR( CEIL(FWeight) ) FROM T_Person
SELECT FWeight, CEILING(FWeight),CHAR(int(CEILING(FWeight))) FROM T_Person

由于DB2 的类型检查机制非常严格,所以在DB2 中需要用int()函数将CEILING()函数的返回值显示的转换为整数类型。

发音匹配度

到目前为止所有关于字符串的匹配都是针对其拼写形式的。
如:检索年龄为“jack”的员工:

[code=java]
SELECT * from T_Person WHERE FName="jack"
[/code]

有时我们不知道一个人姓名的准确拼写,只知道它的发音,如“检索名字发音为和[jeck]类似的人员”,就要进行发音的匹配度测试

SOUNDEX()函数:用于计算一个字符串的发音特征值,这个特征值为一个四个字符的字符串,特征值的第一个字符总是初始字符串中的第一个字符,而其后则是一个三位数字的数值。
如:查询几个名字的发音特征值:

MYSQL,MSSQLServer:
SELECT SOUNDEX("jack"),SOUNDEX("jeck"),
SOUNDEX("joke"),SOUNDEX("juke"),
SOUNDEX("look"),SOUNDEX("jobe")
Oracle:
SELECT SOUNDEX("jack"),SOUNDEX("jeck"),
SOUNDEX("joke"),SOUNDEX("juke"),
SOUNDEX("look"),SOUNDEX("jobe") FROM DUAL
SELECT SOUNDEX("jack"),SOUNDEX("jeck"),
SOUNDEX("joke"),SOUNDEX("juke"),
SOUNDEX("look"),SOUNDEX("jobe") FROM SYSIBM.SYSDUMMY1

执行结果:

SOUNDEX("jack")
SOUNDEX("jeck")
SOUNDEX("joke")
SOUNDEX("juke")
SOUNDEX("look")
SOUNDEX("jobe")
J000 J000 J000 J000 L200 J100

可以看到jack、jeck、joke、juke 几个字符串的发音非常相似,而look、jobe 的发音则和它们差距比较大。
再如:查询公司所有员工姓名的发音特征值:

SELECT FName, SOUNDEX(FName) FROM T_Person

执行结果:

FName SOUNDEX(FName)
Tom T500
Jim J500
Lily L000
Kelly K400
Sam S500
Kerry K600
Smith S530
BillGates B4232

在MSSQLServer和DB2中提供了DIFFERENCE()用来简化两个字符串的发音相似度比较,它可以计算两个字符串的发音特征值,并且比较它们,然后返回一个0至4之间的一个值来反映两个字符串的发音相似度,这个值越大则表示两个字符串发音思想度越大。

如:计算每个人的姓名发音与“Merry”的相似度:

SELECT DIFFERENCE(FName,"Merry") FROM T_Person

执行结果:

FName
Tom Merry 2
Jim Merry 1
Lily Merry 2
Kelly Merry 3
Sam Merry 2
Kerry Merry 3
Smith Merry 0
BillGates Merry 1