我们在写SQL时经常会用的到条件,如果在包含的值都是非零值,那么没有特殊的,但是如在中果的值包含空值(比如后的面跟一个子查询,子查询返回的结果有NULL值),甲骨文又会怎么处理呢?
创建一个测试表t_in
zx@TEST> create table t_in (id 数量); Table 创建。 zx@TEST> insert  into t_in 价值(1); 1,row 创建。 zx@TEST> insert  into t_in 价值(2); 1,row 创建。 zx@TEST> insert  into t_in 价值(3); 1,row 创建。 zx@TEST> insert  into t_in 值(空); 1,row 创建。 zx@TEST> insert  into t_in 价值(4); 1,row 创建。 zx@TEST>提交; Commit 完成。 zx@TEST> select *,得到t_in; ID ---------- ,1 ,2 ,3 以前,4 >现在t_in表中有5条记录
1,在条件中不包含零的情况
zx@TEST> select *,得到t_in where id 拷贝(1、3); ID ---------- ,1 ,3 2,rows 选中。上面的条件等价于id=1或id=3得到的结果正好是2;查看执行计划中可以看到,2 -过滤器(“id”=1或“id”=3)说明我们前面的猜测是正确的
2,在条件包含零的情况
zx@TEST> select *,得到t_in where id 拷贝(1、3、空); ID ---------- ,1 ,3 2,rows 选中。上面的条件等价于id=1或id=3或id=null,我们来看下图当有id=零条件时甲骨文如何处理
从上图可以看出当不管id值为null值或非零值,id=null的结果都是未知的,也相当于假的,所以上面的查结果只查出了1和3两条记录。
查看执行计划看到优化器对在的改写
3,不是条件中不包含空值的情况
zx@TEST> select *,得到t_in where id not 拷贝(1、3); ID ---------- ,2 ,4 2,rows 选中。上面查询的,条件等价于id !=1和id !=3,另外t_in表中有一行为null,它虽然满足!=1和!=3但根据上面的规则,空与其他值做=或!=比较结果都是未知的,所以也只查出了2和4。
从执行计划中看到优化器对在的改写
4,不是条件中包含空值的情况
zx@TEST> select *,得到t_in where id not 拷贝(1、3、空); no rows 选择上面查询的,条件等价于id !=1,身份证!=3和id !=null,根据上面的规则,空与其他值做=或!=比较结果都是未知的,所以整个条件就相当于假的,最终没有查出数据。
从执行计划中查看优化器对在的改写
总结一下,使用在做条件时时始终查不到目标列包含空值的行,如果不是条件中包含空值,则不会返回任何结果,包含在中含有子查询。所以在实际的工作中一定要注意不在里包含的子查询是否包含空值。
zx@TEST> select *,得到t_in where id not 拷贝(select id 得到t_in where id =, 1,趁机id is 零); no rows 选择
官方文档: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
甲骨文的地方条件在中/不包含空时的处理