SQL中函数的合理使用可以增强语句的可读性,ORACL作为一个面向商业化运作的数据库,提供了一些内置函数,可以简化我们的SQL语句,例如在上一节的表(SQL技术-表连接)中,我们如果有以下需求:
查出test_details表明细,并将sex按照字典(1:男,0:女,其他:未知)翻译,为了方便测试,我们增加一个空sex的一行
INSERT INTO TEST_DETAILS (ID, USER_ID, ADDR) VALUES (4, 5, '福建');
没有什么是case when完成不了的,如果完成不了,那么再多一个when
SELECT T.ID,
T.USER_ID,
CASE
WHEN SEX = '1' THEN
'男'
WHEN SEX = '0' THEN
'女'
ELSE
'未知'
END SEX,
T.ADDR
FROM TEST_DETAILS T;
结果如下:

我们发现这个语句比较长,如果很多使用case when的话,会大大降低语句可读性,幸好oracle为我们提供了一些内置函数,简化了类似这些判断的语句,下面将分别讲解decode,nvl,nvl2,nullif,coalesce的使用。
DECODE
非常常见的内置函数,其功能相当于上述例子case when的作用,如下:
SELECT T.ID,
T.USER_ID,
DECODE(T.SEX, '0', '女', '1', '男', '') AS SEX,
T.ADDR
FROM TEST_DETAILS T;
结果相同,但是语句简洁了很多。
decode语法示意如下:
DECODE(COL|EXPRESSION,SERACH1,RESULT1,[SEARCH2,RESULT2,...,] DEFAULT])
第一个可能是某列,或者复杂的表达式,如果该表达式或列的该行等于SEARCH1则返回RESULT1,否则继续判断如果等于SEARCH2则返回RESULT2...如果都不符合,则返回DEFAULT。常用语字典值的转换。
NVL
语法NVL(EXPR1,EXPR2):如果EXPR1是null空值则返回EXPR2,否则返回EXPR1。
需求:
查出test_details表明细,并将sex翻译,如果是空则返回-1,否则返回本身。
SELECT T.ID,
T.USER_ID,
NVL(T.SEX,'-1') AS SEX,
T.ADDR
FROM TEST_DETAILS T;
常用语判空给默认值。
NVL2
语法NVL2(EXPR1,EXPR2,EXPR3):如果EXPR1不是null空值则返回EXPR2,否则返回EXPR3。
有点绕,我们通过实际例子说明,在上述text_details表中增加两个字段mobile和phone,并设置一些值(都是随便输的),如下图:

需求:查出test_details内的userid和对应的联系方式(如果有手机则显示手机,否则查询电话)。
SELECT T.USER_ID, NVL2(T.MOBILE, T.MOBILE, T.PHONE) FROM TEST_DETAILS T;
查询结果如下:

如果再增加一个需求,如果电话为空,则显示为"无联系方式",则需要结合nvl函数,如下:
SELECT T.USER_ID, NVL2(T.MOBILE, T.MOBILE, NVL(T.PHONE, '无联系方式'))
FROM TEST_DETAILS T;
查询结果如下:

当然我们可以转为decode函数实现,只是较为复杂,结果是一样的
SELECT T.USER_ID,
DECODE(T.MOBILE,
NULL,
DECODE(T.PHONE, NULL, '无联系方式', T.PHONE),
T.MOBILE)
FROM TEST_DETAILS T;
NVL2多用于判断是否空值并返回不同表达式。
NULLIF
语法NULLIF(EXPR1,EXPR2):如果两个表达式相等,则返回null,如果两个参数不等,则返回第一个表达式。MYSQL还有判空函数ISNULL(EXPR),ORACLE没有,不再详解。
nullif用处较少,不再举例,如果有需要的场合可以使用。
COALESCE
语法COALESCE(EXPR1,EXPR2,EXPR3,...EXPRn):从左向右判断,返回第一个非null值,表达式只有2个则可以用NVL函数代替,某些情况可以用NVL2代替。
同NVL2内的需求,使用COALESCE如下:
SELECT T.USER_ID, COALESCE(T.MOBILE, T.PHONE, '无联系方式')
FROM TEST_DETAILS T;
其包含了nvl和nvl2实现的功能。
综上所述,decode多用于取代case when简化判断,nvl,nvl2多用于判空,而coalesce则在包含了nvl和nvl2功能基础上,可以支持多表达式判断,nullif使用情况较少。
以上函数都是ORACLE内置函数,在其他数据库例如MYSQL对部分有实现和扩展,并不是全部,在有需要的情况,我们可以自己写函数、函数包来实现功能。




