oralce中exists not exists in not in对于NULL的处理

来源:互联网 发布:淘宝拍照专用手机 编辑:程序博客网 时间:2024/06/05 03:42
1. 先讨论 in 与 not in中存在NULL的情况, sql语句如下: 复制代码 1 select 1 result1 from dual where 1 not in (2, 3); 2 3 4 select 1 result2 from dual where 1 not in (2, 3, null); 5 6 7 select 1 result3 from dual where 1 in (2, 3, null, 1); 8 9 10 select 1 result4 from dual where 1 in (2, 3, null); 复制代码 执行结果: result1 result2 result3 result4 1 没有任何返回值 1 没有任何返回值 说明:in与not in 会跟括号里面的值进行比较是否相等从而得出判断结果,而在oracle中null是无法进行比较的,只能进行判断IS NULL和IS NOT NULL,这就导致in和not in中与null进行比较时会返回false. a in (b, c, d)相当于(a == b) || (a == c) || (a == d), 而 a not in (b, c, d)则相当于(a != b) %26%26 (a != c) %26%26 (a != d) result1返回结果1显而易见,1跟2和3相比都不相等, 类似于(1<>2) %26%26 (1<>3) 结果为true所以返回结果1 result2中(1<>2) %26%26 (1<>3) %26%26 (1<>NULL)前面两个都是true可最后1跟NULL进行比较为false,一招走错满盘皆输就是这个道理,最终结果为false,因此没有返回结果 result3中(1 == 2) || (1 == 3) || (1 == NULL) || (1 == 1)前面三个表达式都是false,但最后一个表达式为true最终结果也就为真了,因此返回1。 result4中(1 == 2) || (1 == 3) || (1 == NULL)三个表达式都为false, 最终结果也就为false了, 无任何结果集返回。 2. 再来看看exists与 not exists的例子 1 select 1 result5 from dual where not exists (select 1 from dual t where t.dummy=null); 2 3 select 1 result6 from dual where exists (select 1 from dual t where t.dummy=null); 执行结果: result5 result6 1 没有任何返回值 说明: exists与not exists相当于一种逻辑判断,exists 的本质就是返回一个布尔值,exists测试关联子查询是否有数据返回,如果有至少一行返回的话则exists判断为真返回true, not exists判断关联子查询是否没有数据返回, 如果没有数据返回则判断为真,返回true。 result5查询中由于NULL不能与任何值作比较,因此自然是不存在t.dummy=null了,关联查询返回结果集为空,not exists逻辑判断结果为true, 最终1被查询出来。 result6查询中存在t.dummy=null, 说不通,关联查询返回结果集为空, 逻辑判断结果为false, 最终外层查询没有任何结果集返回。 3. 最后看一个有挺有意思的查询,从csdn论坛上看的。 复制代码 1 select 'true' from dual where (1,2) not in ((2,3),(2,null)); 2 3 select 'true' from dual where (2,1) not in ((2,3),(2,null)); 4 5 select 'true' from dual where (2,1) not in ((2,3),(null,3)); 6 7 select 'true' from dual where (2,1) not in ((2,3),(null,1)); 复制代码 说明:二元值not in判断,... where (a, b) not in ((c, d), (e, f))类似于((a, b) != (c, d) ) %26%26 ((a, b) != (e, f)),将(a, b)与(c, d)比较看成坐标比较,只要有一个坐标对不上这个就是不相等的,因此上面的式子可以扩展成为 (a != c || b != d) %26%26 (a != e || b != f) 第1行的查询判断为true %26%26 true 结果为true、最终字符'true'得以返回。第3行的查询判断为true %26%26 false 结果为false、最终没有结果返回。第5行的查询判断为true %26%26 true 结果为true、 最终字符'true'得以返回。第7行的查询判断为true %26%26 false 结果为false、 最终没有结果返回。 4. 稍微总结一下: in 在a in (b, c, d, ... , null)中, 括号里面的比较值里面存在NULL的话, 看其它比较值里面是否有跟a相等的值存在, 如果有则返回true, 否则返回false. not in 在 a not in (b, c, d,..., null)中,如果括号里面存在NULL的话, 则一律返回false. exists 在 exists的关联查询条件里面如果存在NULL的话,则内部查询是查询不出结果的,不符合exists至少有一行结果集返回的判断, 因此返回false. not exists 在not exists的关联查询条件里面如果存在NULL的话,则内部查询也是查询不出结果的,符合not exists对于没有结果集返回的预期判断, 因此返回true. 5. 以上是个人的一些观点总结,欢迎大家批评指教。
0 0
原创粉丝点击