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

1.   先讨论 in 与 not in中存在NULL的状况, sql语句以下: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);

 

      执行结果:oracle

result1 result2 result3 result4
1 没有任何返回值 1 没有任何返回值

 

      说明:innot 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) && (a != c) && (a != d)测试

  • result1返回结果1显而易见,1跟2和3相比都不相等, 相似于(1<>2) && (1<>3) 结果为true因此返回结果1
  • result2中(1<>2) && (1<>3) && (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的例子spa

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);

 

 


      执行结果:code

result5 result6
1 没有任何返回值

      

      说明: exists与not exists至关于一种逻辑判断,exists 的本质就是返回一个布尔值,exists测试关联子查询是否有数据返回,若是有至少一行返回的话则exists判断为真返回true, not exists判断关联子查询是否没有数据返回, 若是没有数据返回则判断为真,返回true。blog

 

  • result5查询中因为NULL不能与任何值做比较,所以天然是不存在t.dummy=null了,关联查询返回结果集为空,not exists逻辑判断结果为true, 最终1被查询出来。
  • result6查询中存在t.dummy=null, 说不通,关联查询返回结果集为空, 逻辑判断结果为false, 最终外层查询没有任何结果集返回。

 

3.   最后看一个有挺有意思的查询,从csdn论坛上看的。table

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) ) &&  ((a, b) != (e, f)),将(a, b)与(c, d)比较当作坐标比较,只要有一个坐标对不上这个就是不相等的,所以上面的式子能够扩展成为 (a != c || b != d)  &&  (a != e || b != f)class

  • 第1行的查询判断为true && true 结果为true、最终字符'true'得以返回。
  • 第3行的查询判断为true && false 结果为false、最终没有结果返回。
  • 第5行的查询判断为true && true 结果为true、 最终字符'true'得以返回。
  • 第7行的查询判断为true && 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.    以上是我的的一些观点总结,欢迎你们批评指教。select

相关文章
相关标签/搜索