一.创建一个含表,表中只有一列为id,该列中含有值为NULL的记录

我们在写SQL时经常会用到in条件,如果in包含的值都是非NULL值,那么没有特殊的,但是如果in中的值包含null值(比如in后面跟一个子查询,子查询返回的结果有NULL值),Oracle又会怎么处理呢?

创建一个测试表t_in

linuxidc@linuxidc>create table t_in(id number);

Table created.

linuxidc@linuxidc>insert into t_in values(1);

1 row created.

linuxidc@linuxidc>insert into t_in values(2);

1 row created.

linuxidc@linuxidc>insert into t_in values(3);

1 row created.

linuxidc@linuxidc>insert into t_in values(null);

1 row created.

linuxidc@linuxidc>insert into t_in values(4);

1 row created.

linuxidc@linuxidc>commit;

Commit complete.

查询该表:

linuxidc@linuxidc>select * from t_in;

    ID
----------
1
2
3 4

现在t_in表中有5条记录

1、in条件中不包含NULL的情况

linuxidc@linuxidc>select * from t_in where id in (1,3);

    ID
----------
1
3 2 rows selected.

上面的条件等价于id =1 or id = 3得到的结果正好是2;查看执行计划中可以看到 2 - filter("ID"=1 OR "ID"=3)说明我们前面的猜测是正确的

关于 Oralce的执行计划可以参考博文:http://www.cnblogs.com/Dreamer-1/p/6076440.html

2、in条件包含NULL的情况

 linuxidc@linuxidc>select * from t_in where id in (1,3,null);

     ID
----------
1
3 2 rows selected.

上面的条件等价于id = 1 or id = 3 or id = null,我们来看下图当有id = null条件时Oracle如何处理

从上图可以看出当不管id值为NULL值或非NULL值,id = NULL的结果都是UNKNOWN,也相当于FALSE。所以上面的查结果只查出了1和3两条记录。

查看执行计划看到优化器对IN的改写

3、not in条件中不包含NULL值的情况

linuxidc@linuxidc>select * from t_in where id not in (1,3);

    ID
----------
2
4 2 rows selected.

上面查询的where条件等价于id != 1 and id !=3,另外t_in表中有一行为null,它虽然满足!=1和!=3但根据上面的规则,NULL与其他值做=或!=比较结果都是UNKNOWN,所以也只查出了2和4。

从执行计划中看到优化器对IN的改写

4、not in条件中包含NULL值的情况

linuxidc@linuxidc>select * from t_in where id not in (1,3,null);

no rows selected

上面查询的where条件等价于id!=1 and id!=3 and id!=null,根据上面的规则,NULL与其他值做=或!=比较结果都是UNKNOWN,所以整个条件就相当于FALSE的,最终没有查出数据。

从执行计划中查看优化器对IN的改写

总结一下,使用in做条件时时始终查不到目标列包含NULL值的行,如果not in条件中包含null值,则不会返回任何结果,包含in中含有子查询。所以在实际的工作中一定要注意not in里包含的子查询是否包含null值。

如下在in 语句中的子查询中含有NULL值。

linuxidc@linuxidc>select * from t_in where id not in (select id from t_in where id = 1 or id is null);

no rows selected

官方文档:http://docs.oracle.com/cd/E11882_01/server.112/e41084/sql_elements005.htm#SQLRF51096

http://docs.oracle.com/cd/E11882_01/server.112/e41084/conditions013.htm#SQLRF52169

http://docs.oracle.com/cd/E11882_01/server.112/e41084/conditions004.htm#SQLRF52116

本文转载于:http://www.linuxidc.com/Linux/2017-03/141698.htm

Oracle的条件in包含NULL时的处理的更多相关文章

  1. Oracle的条件in中包含NULL时的处理

    我们在写SQL时经常会用到in条件,如果in包含的值都是非NULL值,那么没有特殊的,但是如果in中的值包含null值(比如in后面跟一个子查询,子查询返回的结果有NULL值),Oracle又会怎么处 ...

  2. oracle中查询条件包含null时

    不能使用=null或者!=null 应该使用is null和is not null

  3. in not in 和 null , in 判断范围中可以包含null,而not in判断不能包括null

    oracle中,任何字符串与null比较得到的结果都是null,而 oracle的判断条件为null时就退出判断(?) 因此判断某个字符串是否在一个集合中时,not in 和 in的结果完全不一样,如 ...

  4. 关于mybatisPlus一些坑,当条件为null时

    1.TStaffDepart 属性有值是才匹配条件,会报错,相当于mybatis if 判断 eg:TStaffDepart staffDepart = new TStaffDepart();staf ...

  5. C#程序读取数据库中包含null的列的值

    private void btn2_Click(object sender, RoutedEventArgs e)         {             using (SqlConnection ...

  6. oracle中一个字符串包含另一个字符串中的所有字符

    oracle中一个字符串包含另一个字符串中的所有字符 --解决监理报告中所勾选的标段信息,与该用户所管理的标段字符串不匹配的问题. select * from a where instr(a,b)&g ...

  7. Oracle“不等于号”与Null的情况

    今天突然才发现,Oracle中的“不等于操作符”是忽略Null的. 比如,查询comm不等于的300的记录,我会理所当然地使用where comm != 300 预想会返回包含Null的不等于300的 ...

  8. 对”唯一键可以包含NULL值,并且每个NULL值都是唯一的(即NULL!=NULL)“理解

    因为最近在写一篇关于字符串模糊检索的论文,开始比较细致的研究数据库(MySQL)中的index问题,变到图书馆借了本<Effective MySQL之SQL语句最优化>(Ronald Br ...

  9. Oracle 11G在用EXP 导出时,空表不能导出解决

    Oracle 11G在用EXP 导出时,空表不能导出解决 (转)(.http://wanwentao.blog.51cto.com/2406488/545154 11G中有个新特性,当表无数据时,不分 ...

随机推荐

  1. PAT A1010.Radix 二分法

    PAT A1010.Radix 链接: https://pintia.cn/problem-sets/994805342720868352/problems/994805507225665536 算法 ...

  2. WebDriver中的操作使用

    1.WebDriver中使用jquery假如设定jquery包的路径为path,则程序如下: String jquery=null; FileInputStream input = new FileI ...

  3. 别人的Linux私房菜(17)进程管理与SELinux初探

    程序在磁盘中,通过用户的执行触发.触发事件时,加载到内存,系统将它定义成进程,给予进程PID,根据触发的用户和属性,给予PID合适的权限. PID和登陆者的UID/GID有关.父进程衍生出来的进程为子 ...

  4. Linux---基础指令(一)

    https://www.linuxprobe.com/chapter-02.html  (Linux就要这么学) 一.执行查看帮助命令 date:date命令用于显示及设置系统的时间或日期,格式为“d ...

  5. ehcache缓存使用

    CacheUtils.java //工具类 保存cache缓存: CacheUtils.put(CacheUtils.SIGN_CACHE, childid + "_" + mNu ...

  6. 第49章:MongoDB-数据导入导出

    ①导出工具mongoexport Mongodb中的mongoexport工具可以把一个collection导出成JSON格式或CSV格式的文件.可以通过参数指定导出的数据项,也可以根据指定的条件导出 ...

  7. [译]迁移到新的 React Context Api

    随着 React 16.3.0 的发布,context api 也有了很大的更新.我已经从旧版的 api 更新到了新版.这里就分享一下我(作者)的心得体会. 回顾 下面是一个展示如何使用旧版 api ...

  8. python按照指定字符或者长度 截取字符串

    1.截取指定位置字符串 Python字符串可以理解为一个数组,获取某一部分的可以使用 str[beginIndex:endPosition],其中str为需要截取的字符串,beginIndex为需要截 ...

  9. 关于信息系统设计与开发——案例:VIP系统

    一.关于信息系统设计与开发 信息系统开发流程先对需求分析系统分析,设计数据库,设计程序,再对测试数据进行测试. 在程序设计中运用了接口:定义一个接口,可以有多种实现.变量声明为接口变量,调用接口方法, ...

  10. 当input中的type值为file时,各浏览器的表现形式不同

    如果想使各浏览器下的表现形式相同,需要对该input元素隐藏,然后再改元素下方添加标签.其html写法如下 <div class="input-file"> <i ...