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) && (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的例子

 select 1 result5 from dual where not exists (select 1 from dual t where t.dummy=null);

 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论坛上看的。

 select 'true'  from dual where (1,2) not in ((2,3),(2,null));

 select 'true' from dual where (2,1) not in ((2,3),(2,null));

 select 'true' from dual where (2,1) not in ((2,3),(null,3));

 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)

  • 第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.    以上是个人的一些观点总结,欢迎大家批评指教。

oralce中exists not exists in not in对于NULL的处理的更多相关文章

  1. Oracle中没有 if exists(...)

    对于Oracle中没有 if exists(...) 的语法,目前有许多种解决方法,这里先分析常用的三种,推荐使用最后一种 第一种是最常用的,判断count(*)的值是否为零,如下declare  v ...

  2. SQL中IN,NOT IN,EXISTS,NOT EXISTS的用法和差别

    SQL中IN,NOT IN,EXISTS,NOT EXISTS的用法和差别: IN:确定给定的值是否与子查询或列表中的值相匹配. IN 关键字使您得以选择与列表中的任意一个值匹配的行. 当要获得居住在 ...

  3. ORACLE 中IN和EXISTS比较

    ORACLE 中IN和EXISTS比较 EXISTS的执行流程      select * from t1 where exists ( select null from t2 where y = x ...

  4. 面试被问之-----sql优化中in与exists的区别

    曾经一次去面试,被问及in与exists的区别,记得当时是这么回答的:''in后面接子查询或者(xx,xx,xx,,,),exists后面需要一个true或者false的结果",当然这么说也 ...

  5. (转)MySQL中In与Exists的区别

    背景:总结mysql相关的知识点. 如果A表有n条记录,那么exists查询就是将这n条记录逐条取出,然后判断n遍exists条件. select * from user where exists s ...

  6. 数据库中in和exists关键字的区别

    数据库中in和exists关键字的区别 in 是把外表和内表作hash join,而exists是对外表作loop,每次loop再对内表进行查询. 一直以来认为exists比in效率高的说法是不准确的 ...

  7. SQL中IN和EXISTS用法的区别

    结论 1. in()适合B表比A表数据小的情况 2. exists()适合B表比A表数据大的情况 当A表数据与B表数据一样大时,in与exists效率差不多,可任选一个使用. select * fro ...

  8. [转]Oracle中没有 if exists(...)

    本文转自:http://blog.csdn.net/hollboy/article/details/7550171 对于Oracle中没有 if exists(...) 的语法,目前有许多种解决方法, ...

  9. SQL查询中in和exists的区别分析

    select * from A where id in (select id from B); select * from A where exists (select 1 from B where ...

随机推荐

  1. 2-16 HDO1106

    这题寒假也没搞出来,但今天花了一小时终于搞定. 题意是输入一串数字字符,把‘5’当作空格,然后把被分割开的数字进行排序输出. 首先是字符串输入,按照高精度的处理方法,数值低位放到数组低位.(字符串型的 ...

  2. easyui combo+pagination 图标选择器

    从数据库读取分页显示 $(function () { initTable(1, 180); $('#cc').combo({ editable: false, panelWidth: 'auto', ...

  3. codeforces 305E Playing with String

    刚开始你只有一个字符串每次能选择一个有的字符串s,找到i,满足s[i - 1] = s[i + 1],将其分裂成3 个字符串s[1 ··  i - 1]; s[i]; s[i + 1 ·· |s|] ...

  4. WPS怎样设置多级标题(如四级标题)

    WPS期初,乍一看最多只能设置三级标题. 怎样设置四级以上标题呢? 这里以设置四级标题为例: 点击‘视图’->'大纲', 假如,现在2.3.3这一行是三级标题: 在下拉框里选择‘4级’就可以了. ...

  5. angular2 学习笔记 ( DI 依赖注入 )

    refer : http://blog.thoughtram.io/angular/2016/09/15/angular-2-final-is-out.html ( search Dependency ...

  6. sql优化(oracle)

    系统优化中很重要的方面是SQL语句的优化,对于海量数据,优质的SQL能够有效的提高系统的可用性. 总结的有点罗嗦,列个简单的目录啦~ 目录 第一部分知识准备                      ...

  7. HDOJ(HDU) 1799 循环多少次?(另类杨辉三角)

    Problem Description 我们知道,在编程中,我们时常需要考虑到时间复杂度,特别是对于循环的部分.例如, 如果代码中出现 for(i=1;i<=n;i++) OP ; 那么做了n次 ...

  8. Exception testing

    怎样去验证代码是否抛出我们期望的异常呢?虽然在代码正常结束时候验证很重要,但是在异常的情况下确保代码如我们希望的运行也很重要.比如说: new ArrayList<Object>().ge ...

  9. I - Navigation Nightmare-poj 1984

    约翰和他的邻居生活在一个村庄里,他们的道路修建的很特别,都是正东正西或者正南正北,但是呢他们用一种方式描述他们和邻居的位置,比如说 6号 在1号 东面13处,那么我们就可以计算出来这两家的曼哈顿距离, ...

  10. HTTP学习实验8-windows添加telnet功能

    Windows 添加telnet功能: 控制面板->(查看方式:小图标)->程序和功能->打开或关闭Windows功能->Telnet客户端 Telnet 设置: 打开cmd, ...