首先,大家可以先试着做这道练习题☞
题目:
给定一个表 T,id 是树节点的编号, pid 是它父节点的 id 。
树中每个节点属于以下三种类型之一:
叶子:如果这个节点没有任何孩子节点。
根:如果这个节点是整棵树的根,即没有父节点。
内部节点:如果这个节点既不是叶子节点也不是根节点。
写一个查询语句,输出所有节点的编号和节点的类型,并将结果按照节点编号排序。上面样例的结果为:
一开始我的查询语句是这样写的☞
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
查询结果如下,明显是错误的

当我分解语句时发现,当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 )
查询结果: 查询不会返回任何值

二、not in () 查询列包含NULL 值
select * from T where PID not in (1)
查询结果: 查询不到NULL值

三、in (包含NULL值)
select * from T where PID in (NULL,1)
查询结果: 查询不到NULL值

总结:
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
PID = NULL 返回是False,因为关联条件用的是or,这个条件会被忽略
select * from T where PID not in (NULL,1)
这句查询语句相当于
select * from T where PID <> NULL AND PID <> 1
PID = NULL 返回是False,因为关联条件用的是and,所以语句匹配不到任何值
我们可以在IN函数的参数列表中使用COALESCE函数,将空值替换为一个非NULL的默认值。为了正确处理空值,可以使用IS NULL和IS NOT NULL运算符,或者使用COALESCE函数将空值替换为一个非NULL的默认值。在MySQL中,当值列表中包含空值时,IN函数的结果将始终为NULL,而不是TRUE或FALSE。这是因为IN函数的结果为NULL,而不是TRUE或FALSE。其中,column_name是要匹配的列名,table_name是要查询的表名,value1、value2等是要匹配的值。
用in的时候一般问题不大,使用not in的时候需要特别主要,结合本文恰当使用,之所以
造成如此大的差异原因是对NULL的判断上,NULL的判断本质上is null或is not null,in或
not in的判断是等于(=),所以对NULL判断是无效的,需要谨记。.........
前两天做问题排查的时候,写了一条sql,但是并没有如期地查到数据(确实是有数据的),SQL如下:
SELECT tar.*
FROM tb_account_relation tar
WHERE tar.customer_id
NOT IN (
SELECT customer_id
FROM TB_SMS_SEND_DETAIL
WHERE TYPE = '2'
所以在使用not in 时需要注意数据中是否有null,并且null的判断使用的是is null, 或者is not null, 使用=是不行的。并且在MySQL中, null代表的就是缺失未知值而不是空值, null与任何值用<>=等运算符判断时候返回的都是null。判断时,返回的结果是null不是ture,所以这个not in语句的返回值是False。所有的记录只要返回一条True, in语句返回的就是True, 所有即使。使用in判断的时候就不会出现这样的问题, 比如。返回的结果是null。
1)in的逻辑规则是or not in 的逻辑规则是 and
2)判断null 的sql语句为 is not null 或者 is null
3)当遇到 null = null 的判断是时由于不符合null的判断规则,所以结果一定为flase
not in 中包含null值的情况
select *
from A
where A.name not in
(select B.name
from B )
在上面的not in的查询中如果B表的name字段.
select code from "D"这个语句的结果包含了null值,但是在in中,会自动忽略null值;
select * from "C" where code not in (select code from "D");
上面这个语句跑出来的结果是空,原因是not in中包含了null值,会直接返回false,导致整个whe