mysql:not in(子查询),子查询中存在Null值的情况分析与解决

score1:

score2: 

当我们经常在where子句过滤条件中使用not in时 ,如:

 查询score1分数不在score2分数中的数据,:

select * from score1 where 成绩 not in (select 成绩 from score2);

可能会遇到where返回结果全为False的情况,即使确实不存在于子查询中,仍然返回为False

如下查询结果:

 由表格可知score1中存在成绩为77且不存在于score2表的成绩中的数据,可查询结果却为空;

我们使用:select 77 in (select 成绩 from score2);尝试查看返回的结果。

而: select 88 in (select 成绩 from score2);

由上可知,77 not in 返回null值, 而88 not in 返回 0值;

88 not in结果为0即假值符合我们的预期,而77 not in 理应返回1即真值,可却返回Null值 导致结果也为假值。

原因:

        当使用in时,具体实现过程是将每个值与结果集中的每个值进行对比,当你判断任意值a = null时, 官方说, "You cannot use arithmetic comparison operators such as =, <, or <> to test for NULL", 任何与null值的对比都将返回null而不是假值0。

         当询问 成绩 not in (select 成绩 from score2)时, 因为score2.成绩null值, 则77 in (88,82,88,93,null)的结果是(0,0,0,0,null),当集合中只有0与null时,程序会返回null而不是0假值,取not仍然为null;而88 not in 中仍然返回0,原因在于如88 in (88,82,88,93,null)的结果是 (1,0,1,0,null),则含有真值则覆盖null返回真值,然后取 not 才得到0的假值结果。

解决:

        只需要在not in的基础上加上 is  null判断即可,如下:

 由以上分析我们可知当我们想要的not in 返回真值时都会返回null而想要的not in 为假值仍然返回0,则只需要加上is null判断即可。

注:首先需确定子查询中是否含有Null值。

猜你喜欢

转载自blog.csdn.net/weixin_46707493/article/details/127132535