mysql在和不在的危险

roejwanj  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(245)

我已经阅读了有关mysql的文档 IN 以及 NULL . 看这里:包含any、in或some的子查询,包含all的子查询
我做了一些实验。

创建表(MySQL5.6)

CREATE TABLE `test` (
  `uid` bigint(20) NOT NULL,
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO  test(uid) values (1),(2),(3),(4),(5);

声明1.1:

select 2 union all (select null);
+------+
|      |
+------+
|    2 |
| NULL |
+------+

声明1.2:

select uid from `test` where uid not in (select 2 union all (select null));  
+------+
|      |
+------+
|      |
+------+

声明1.3:

select uid from `test` where 1 not in (select 2 union all (select null));  
+------+
|      |
+------+
|      |
+------+

到目前为止,一切都按计划进行。但是现在我们修改了这个语句,混乱的事情发生了。

声明2.1:

select 2 union all (select null from test);
+------+
|      |
+------+
|   2  |
+------+
| NULL |
+------+
| NULL |
+------+
| NULL |
+------+
| NULL |
+------+
| NULL |
+------+

声明2.2:

select uid from `test` where uid not in (select 2 union all (select null from test));
+------+
|      |
+------+
|  3   |
+------+
|  4   |
+------+
|  5   |
+------+

声明2.3:

select uid from `test` where 1 not in (select 2 union all (select null from test)); 
+------+
|      |
+------+
|      |
+------+

声明2.4:

select uid from `test` where uid not in (select 3 union all (select null from test));
+------+
|      |
+------+
|  2   |
+------+
|  4   |
+------+
|  5   |
+------+

声明2.5:

select uid from `test` where 1 not in (select 3 union all (select null from test)); 
+------+
|      |
+------+
|      |
+------+

有人能解释2.2,2.4吗?当我们使用表达式或常量作为操作数时,结果是不一致的?为什么 1 没有出现在2.2和2.4的结果中?似乎2.3和2.5应该是正确的,正如mysql的文档所描述的那样。

8ehkhllq

8ehkhllq1#

NOT IN 返回的子查询 NULL 应始终返回0行。
相关:not in子句和null值。
它看起来像一个bug,在mysql 8.0上是不可复制的。
查询:

select uid from test where uid not in (select 2 union all (select null));
select uid from test where 1 not in (select 2 union all (select null));
select uid from test where uid not in(select 2 union all (select null from test));
select uid from test where uid not in(select 3 union all (select null from test));
select uid from test where 1 not in (select 3 union all (select null from test));
-- 0 rows selected

dbfiddle演示

相关问题