子查询中的NULL问题

子查询返回有单行,多行和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是可以查找出来的。

时间: 2024-10-01 02:17:07

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

oracle子查询中not in后面不能为null值的理解

首先说说oracle中的null值吧. null在oracle中代表未知,表示可能有,也可能没有.任何与null值的普通运算都为null,但可以用一些函数来处理null值,oracle排序中默认null最大. 接着进入正文 这里in后面有null,能返回数据 但加了not后,就不能返回数据了 这里的in后面的句子可以理解为or拼接,即 id in (200,201,null)可以等价于id=200 or id=201or id=null, id not in (200,201,null)可以等价

子查询中包含不存在的列--居然不是bug!

1.现象 create table a as (select 1 as col_a); create table b as (select 2 as col_b)  select *  from a  where col_a in (select col_a from b) 其中,col_a只存在于table_a中,table_b中没有该字段,整条语句的结果是可以成功执行! 2.原因: 这个问题比较困惑,网上搜到的原因是"当子查询中的列名不存在时,自动向外层寻找". 也就是说,上面的查

如何在子查询中实现多列过滤

什么是子查询: 当一个查询是另外一个查询的条件,称之为子查询. 常见子查询使用场景: 1.使用子查询可以避免由于子查询中的数据产生的重复. 2.使用子查询更符合语义,更好理解 -- 子查询user_id 重复时,不会导致结果重复 select user_name from qujing where id in (select user_id from user_kills); -- 使用join时,会重复 select a.user_name from qujing a join user_ki

子查询中不能使用limit或者in

select * from  wechat_account_info  where id in(select id from wechat_account_info where groupId ='8' ORDER BY id limit 15  ) as s 此句执行中会出现如下错误: [Err] 1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' 原因: MYSQL子查询不支持

mysql 子查询中 使用 limit

如果sql语句中的子查询包含limit 例如: select * from a where id in (select id from b limit 3) 会报错:This version of MySQL doesn’t yet support ‘LIMIT & IN/ALL/ANY/SOME subquery' # 解决办法: 1.加一层子查询 例如:select * from a where id in (select t.id from (select id from b limit

oracle 子查询 嵌套查询 子查询用有null问题

通常情况下, 数据库中不要出现null,最好的做法加上非空约束Not null,null值并不代表不占空间, char(100) null占100个字符 1 --查询不是领导的信息(含null值错误写法) 2 3 select * from emp where empno not in (select mgr from emp); --查询不到记录 4 5 select * from emp where empno <>all(select mgr from emp);--上行等价写法 6 7

thinkphp3.2.3子查询中遇到的错误

使用buildSql方法 $subQuery = $model->field('id,name')->table('tablename')->group('field')->where($where)->order('status')->buildSql(); $model->table($subQuery.' a')->where()->order()->select(): 当我们把里面的.' a'去掉时运行会出现错误,因为每个派生出来的表(即

子查询中可以包含order by 子句--(在from里面)

select a.* from dept a where a.deptno in (select b.deptno from emp b order by b.deptno)  --在where后面报错: ORA-00907: missing right parenthesis ; --from后面的视图是内联视图,可以使用order by --如上报错语句再嵌套一层变成from后面的内联视图就好了 --例如: select a.* from dept a where a.deptno in (

MySQL左右连接查询中的NULL的数据筛选问题

原文地址:https://www.cnblogs.com/alonely/p/10452448.html