子查询返回有单行,多行和null值;适用于单行子查询的比较运算符是=,>,>=,<,<=<>和!=。适用于多行子查询的比较运算符是in,not in,any和any。在子查询中不可回避的是会返回null值,下面就这个问题来讨论一下。

在单行子查询中
SQL> select last_name,department_id from  employees where department_id is null;
LAST_NAME DEPARTMENT_ID
------------------------- -------------
Grant

先来查看一下employees表中的department_id,它有个null值。

SQL> select last_name,department_id from  employees
where department_id=(select department_id from employees where last_name='Haus');
no rows selected

在employees表中没有一行的last_name是等于Haus的,故子查询返回null值。由上面的查询知道department_id是有null值的,那没有显示呢?

这是因为任何运算(加减乘除、字符串连接等)的运算数中包括NULL值时,整个表达式的值即为NULL。使用单行函数对NULL值进行处理,得到的结果也为NULL(NVL等函数除外)。
 
2.在多行子查询中
SQL> select employee_id,manager_id from employees   where manager_id is null;
EMPLOYEE_ID MANAGER_ID
----------- --- -------
100

先来查看一下employees表中的manager_id,它有个null值。

SQL> select  last_name  from employees  where  employee_id  not in (select manager_id from
employees );
no rows selected

那这个为什么也没有显示?我们来先看一下in

SQL> select  last_name  from employees emp where emp.employee_id  in (select manager_id from employees);
LAST_NAME
-------------------------
Cambrault
De Haan
Errazuriz
Fripp

这里用in可以显示了。这个原因是因为not in 和in本质上都是OR运算,但是计算逻辑OR时处理NULL的方式不同,产生的结果也不同。

 
为了说明上面的问题,我们来看一下NULL在布尔预算中的规则:
        由于NULL是未知,所以NULL AND NULL、NULL OR NULL、NULL AND TRUE和NULL OR FALSE的值都是未知的,这些的结果仍然是NULL。那么为什么NULL AND FALSE和NULL OR TRUE得到了一个确定的结果呢?仍然从NULL的概念来考虑。NULL是未知的,但是目前NULL的类型是布尔类型,因此NULL只有可能是TRUE或者FALSE中的一个。所以NULL AND FALSE的结果是FALSE,NULL OR TRUE的结果是TRUE。
 
 
有了这个我们就能解释上面的问题了,对于
select  last_name  from employees  where  employee_id  not in (select manager_id from
employees );

子查询select manager_id from employees会产生很多值而且有一个NULL值,它们之间是OR的关系,假设manager_id是10,11和NULL,那么可以把上面的句子改为:

select  last_name  from employees  where  employee_id  not in (10,11,null);

其中where  employee_id  not in (10,11,null)等价于where no (employee_id=10 or employee_id=11 or employee_id=null),拿employee_id=12来说明一下。

not (12=10 or 12=11 or 12=null)
not(false or false or null) (OR运算,null不确定,所以整个表达式为null)
not null (这是布尔运算中,NULL表示的是未知的含义,而增加一个NOT操作后,并不能使NULL变为一个确定的值,如果是TRUE,NOT TRUE将变为FALSE,如果是FALSE,NOT FALSE将变为TRUE,值不确定,所以为null)
null
所以结果显示为no rows selected
 
对于
select  last_name  from employees emp where emp.employee_id  in (select manager_id from employees);

按照上面的方法,假设manager_id是10,11和NULL,则句子改为:

select  last_name  from employees  where  employee_id  not in (10,11,null);

其中where  employee_id  in (10,11,null)等价于where  (employee_id=10 or employee_id=11 or employee_id=null),拿employee_id=10来说明一下。

(10=10 or 10=11 or 10=null)
(true or false or null)(OR运算有一真则表达式为真)
true
所以in是可以查找出来的。

子查询中的NULL问题的更多相关文章

  1. oracle 子查询中null的问题(in 和 not in)

    这里的in后面的句子可以理解为or拼接,简单举例即 in (9566,9839,null)可以等价于mgr=9566 or mgr=9839 or mgr=null, not in (9566,983 ...

  2. SQLSERVER 子查询中使用ORDER BY

    SQLSERVER如何在子查询中使用ORDER BY 今天在使用公司的一个pager接口的时候,需要传递一个查询的SQL语句,因为我希望他能够在pager对他查询出来的结果排序之前自己先进行排序, 于 ...

  3. 【杂记】mysql 左右连接查询中的NULL的数据筛选问题,查询NULL设置默认值,DATE_FORMAT函数

    MySQL左右连接查询中的NULL的数据筛选问题 xpression 为 Null,则 IsNull 将返回 True:否则 IsNull 将返回 False. 如果 expression 由多个变量 ...

  4. SQLSERVER如何在子查询中使用ORDER BY

    今天在使用公司的一个pager接口的时候,需要传递一个查询的SQL语句,因为我希望他能够在pager对他查询出来的结果排序之前自己先进行排序, 于是在这个SQL中添加了ORDER BY,但是得到的结果 ...

  5. Mybatis 一对多延迟加载,并且子查询中与主表字段不对应 (19)

    Mybatis  一对多延迟加载,并且子查询中与主表字段不对应应用说明. 实现一对多关联(懒加载),一个教研组对应多个教师,既:教师的教研编号与教研组的教研编号关联,并且教师关联教研组外键与教研组编号 ...

  6. Mysql in子查询中加limit报错

    Mysql in子查询中加limit报错 select id from aa where id in ( select id from bb limit 10 ); 改写成 SELECT id FRO ...

  7. Oracle子查询中any、some、all之间的区别

    用some,any和all对子查询中返回的多行结果进行处理. 下面我们来简单介一下这几个关键词的含义. * Some在此表示满足其中一个的意义,是用or串起来的比较从句. * Any也表示满足其中一个 ...

  8. mysql更新子查询中的内容

    UPDATE t_finance_certify_copy c SET c.biz_type=2,c.sub_biz_type=18WHERE c.finance_certify_id IN(SELE ...

  9. MySQL也真是让人郁闷(关于子查询中使用limit)

    在MySQL4.1中子查询是不能使用LIMIT的,手册中也明确指明 “This version of MySQL doesn’t yet support ‘LIMIT & IN/ALL/ANY ...

随机推荐

  1. 深入浅出JavaScript之跨域总结

    什么是跨域 1.document.domain+iframe的设置 2.动态创建script 3.利用iframe和location.hash 4.window.name实现的跨域数据传输 5.使用H ...

  2. 【BZOJ】3456: 城市规划 动态规划+多项式求逆

    [题意]求n个点的带标号无向连通图个数 mod 1004535809.n<=130000. [算法]动态规划+多项式求逆 [题解]设$g_n$表示n个点的无向图个数,那么显然 $$g_n=2^{ ...

  3. 20155321 2016-2017-2 《Java程序设计》第六周学习总结

    20155321 2016-2017-2 <Java程序设计>第六周学习总结 教材学习内容总结 第十章 IO 流 IO 流用来处理设备之间的数据传输 Java对数据的操作是通过流的方式 J ...

  4. 【译】第十篇 Replication:故障排除

    本篇文章是SQL Server Replication系列的第十篇,详细内容请参考原文. 复制故障排除是一项艰巨的任务.在任何复制设置中,都涉及到很多移动部件,而可用的工具并不总是很容易识别问题.Th ...

  5. VMware虚拟机 安装centos7并设置静态ip 连接外网

    首先下载VMware虚拟机:http://xzc.197746.com/VMware-Workstation-12.5.9.zip 然后下载centos7镜像:http://vault.centos. ...

  6. 延迟注入工具(python)

    延迟注入工具(python) #!/usr/bin/env python # -*- coding: utf-8 -*- # 延迟注入工具 import urllib2 import time imp ...

  7. mysql取字段名注意事项!!!!千万不能和关键字同名

    今天就碰到一个恶心的问题,更新时update sql语句报错,查了半天感觉没问题啊,后来一行一行定位,终于找到原因了, 原来是有个字段是show,和mysql关键字冲突了,坑爹! 改了个名字就好了,或 ...

  8. python(13)多线程:线程池,threading

    python 多进程:多进程 先上代码: pool = threadpool.ThreadPool(10) #建立线程池,控制线程数量为10 reqs = threadpool.makeRequest ...

  9. 如何禁止Linux内核的-O2编译选项【转】

    转自:http://blog.csdn.net/larryliuqing/article/details/8674274 http://lenky.info/2013/03/10/%E5%A6%82% ...

  10. Linux input子系统学习总结(一)---- 三个重要的结构体

    一 . 总体架构 图 上层是图形界面和应用程序,通过监听设备节点,获取用户相应的输入事件,根据输入事件来做出相应的反应:eventX (X从0开始)表示 按键事件,mice 表示鼠标事件 Input ...