SQL 中in 和not in 遇到NULL 值的查询情况

首先,大家可以先试着做这道练习题☞

题目:
给定一个表 T,id 是树节点的编号, pid 是它父节点的 id 。
SQL 中in 和not in 遇到NULL 值的查询情况_第1张图片
树中每个节点属于以下三种类型之一:
叶子:如果这个节点没有任何孩子节点。
根:如果这个节点是整棵树的根,即没有父节点。
内部节点:如果这个节点既不是叶子节点也不是根节点。
写一个查询语句,输出所有节点的编号和节点的类型,并将结果按照节点编号排序。上面样例的结果为:
SQL 中in 和not in 遇到NULL 值的查询情况_第2张图片
一开始我的查询语句是这样写的☞

select ID,CASE WHEN PID IS NULL THEN 'Root'
    when ID not in (SELECT  PID FROM T ) THEN 'Leaf'
    else 'Inner' end as Type
from T

查询结果如下,明显是错误的
SQL 中in 和not in 遇到NULL 值的查询情况_第3张图片
当我分解语句时发现,当not in() 里面包含null值,查询不会返回任何值。

所以这题正确的查询语句应该是☞

--建表
if object_id('T','U') is not null drop table T
CREATE TABLE T(ID INT,PID INT);
INSERT INTO T VALUES (1,null);
INSERT INTO T VALUES (2,1);
INSERT INTO T VALUES (3,1);
INSERT INTO T VALUES (4,2);
INSERT INTO T VALUES (5,2);
--查询
select ID,CASE WHEN PID IS NULL THEN 'Root'
    when ID not in (SELECT  PID FROM T WHERE PID IS NOT NULL) THEN 'Leaf'
    else 'Inner' end as Type
from T

案例分析:
一、not in (包含NULL值)

select * from T where ID not in (SELECT PID FROM T )

查询结果: 查询不会返回任何值
SQL 中in 和not in 遇到NULL 值的查询情况_第4张图片

二、not in () 查询列包含NULL 值

select * from T where PID not in (1)

查询结果: 查询不到NULL值
SQL 中in 和not in 遇到NULL 值的查询情况_第5张图片
三、in (包含NULL值)

select * from T where PID  in (NULL,1)

查询结果: 查询不到NULL值
SQL 中in 和not in 遇到NULL 值的查询情况_第6张图片


总结:
in 匹配的时候用的是 =
not in 匹配的时候用的是 <>
NULL 只能用 is null 或者 is not null 来判定

那么

select * from T where PID  in (NULL,1) 

这句查询语句相当于

select * from T where PID = NULL or PID = 1 --注意这里是OR关联条件

PID = NULL 返回是False,因为关联条件用的是or,这个条件会被忽略


select * from T where PID not in (NULL,1) 

这句查询语句相当于

select * from T where PID <> NULL AND PID <> 1  --注意这里用的是and联接条件

PID = NULL 返回是False,因为关联条件用的是and,所以语句匹配不到任何值

你可能感兴趣的:(数据库,sql,数据库)