NULL值的处理和Oracle9新增函数

什么是空值(NULL)
NULL值是一个很特别的值。它既不是零,也不是空格。它的值是没有定义的、未知的、不确定的。
形象比喻:一个英俊的少年向一位妙龄少女求婚。它可能会说:“我将我所有的爱奉献给您”。现在它的市场价值是多少呢?NULL,可能是一文不值的谎言,也可能是价值无限,造成这种现象的主要原因是信息不完全。

含有空值(NULL)的表达式的运算
只要一个表达式中包含任何NULL(空值),该表达式的值就为NULL。刚才的例子,少女做了一件十分令少年伤心的事,少年气愤的说:“我对您的爱已经减了一层”,我们还是不知道它的爱的市场价值,也就还是NULL值。
SELECT * FROM USER_BASE_INFO WHERE USER_ID != NULL;
以NULL作为条件查出来的全是空值。这是因为我们不能确定NULL的值,也就不能使用NULL进行确定的比较。

为了解决这个进退两难的问题,Oracle引入了一个新的运算符IS NULL来处理这类问题
SELECT * FROM USER_BASE_INFO WHERE USER_ID IS NOT NULL; -- 好多值
SELECT * FROM USER_BASE_INFO WHERE USER_ID IS NULL

空值(NULL)的排序
SELECT SIGN_IN_DATE FROM USER_BASE_INFO ORDER BY SIGN_IN_DATE ASC;
测试的出:升序NULL值排在最后,降序NULL值排在最前,也就是说,NULL值最小

逻辑表达式和逻辑运算符
oracle提供了AND、OR和NOT三个逻辑运算符
在二值逻辑中逻辑表达式或条件只能为真或假。这种情况下的结果就不必多说了
AND:有F则为F,其他T
OR:有T则为T,其他F
NOT:T-->F F-->T
引入NULL:
AND:
if(有F) return F;
else{
if(有NULL){
return IS NULL;(return的是IS NULL而不是NULL,是因为=NULL作为条件的话会污染条件)
}else{
正常二值逻辑
}
}
OR:
if(有T) return T;
else{
if(有NULL){
return IS NULL;
}else{
正常二值逻辑
}
}
NOT:
if(T) return F;
else if(F) return T;
else if(NULL) return IS NULL;

运算符的优先级:
1、算术运算符
2、连接运算符
3、比较运算符
4、IS NULL,IS NOT NULL、LIKE、NOT LIKE、IN、NOT IN
5、BETWEEN,NOT BETWEEN
6、NOT
7、AND
8、OR

NVL函数
我们知道NULL值具有感染性,基本上与NULL进行算术运算得到的都是NULL,有些时候我们希望将感染变得可控,我们可以使用NVL函数,如果为NULL的话,我们给它一个默认值
NVL(表达式|值,默认值):空值转换函数
SELECT NVL(SIGN_IN_DATE,'没有指定') FROM USER_BASE_INFO;

DECODE函数:sql中没有逻辑判断语句,所以Oracle引入了DECODE函数完成类似的功能
DECODE(输入内容,值1,对应值1,值2,对应值2,...[缺省值])。其实和java中的if。。else if。。else if。。。else。。。类似
SELECT USER_ID,DECODE(MOB_BELONG_TO,'安徽','皖','上海','沪','江西','赣','吉安') FROM USER_BASE_INFO;

单行函数的嵌套

oracle9i引入的新函数
NVL2:对nvl进行了拓展,将不为null返回的值变成了可配置
NVL2(表达式1,表达式2,表达式3)表达式1不为空,返回表达式2的值,表达式1为空,返回表达式3的值
表达式2和表达式3可以是除LONG以外的任何数据类型,表达式2和表达式3的类型如果不同,oracle就把表达式2的数据类型转换成表达式2的数据类型;如果此时表达式3为控制,就不进行数据类型的转换
select NVL2(BIRTH_DATE,TO_CHAR(TO_DATE(birth_date,'YYYYMMDD'),'YYYY-MM-DD'),'没有填') from user_base_info;

NULLIF(表达式1,表达式2):NULLIF函数比较表达式1和表达式2,如果两个表达式相等就返回空值(NULL),如果不相等就返回表达式1,表达式1不能为NULL
SELECT NULLIF(
(SELECT MOB_BELONG_TO FROM USER_BASE_INFO WHERE USER_ID = '00000000108'),
(SELECT MOB_BELONG_TO FROM USER_BASE_INFO WHERE USER_ID = '00000000005')
) AS "共同属于省份" FROM dual;

COALESCE(合并,联合)
COALESCE(表达式1,表达式2,表达式3,...,表达式n)
SELECT COALESCE(BIRTH_DATE,SIGN_IN_DATE,NAME_CN) FROM USER_BASE_INFO;
如果表达式1为null,则匹配表达式2,如果表达式3为空则匹配表达式3,。。。匹配到的第一个不为空返回就不往后执行。有点类似java的一个循环找非空,找到跳出循环并返回

CASE
CASE 表达式1 WHEN 匹配1 THEN 结果1 。。。ELSE ...THEN END.就是类似switch。
SELECT CASE MOB_BELONG_TO
WHEN '安徽' THEN '加林'
WHEN '日照' THEN '黎明'
WHEN '上海' THEN '假名'
ELSE '果真'
END "本地人"
FROM USER_BASE_INFO;

posted @ 2016-12-24 14:37  guodaxia  阅读(158)  评论(0)    收藏  举报