mysql - 关于 mysql 的 IN 和 NOT IN 的危险

标签 mysql

关于mysql的INNULL的文档我都看过了。看这里: Subqueries with ANY, IN, or SOME , Subqueries with ALL

我做了一些实验。

创建表(MySQL 5.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)); 
+------+
|      |
+------+
|      |
+------+

有人能解释一下statement2.2,2.4吗?当我们使用表达式或常量作为操作数时,结果不一致?为什么 1 没有出现在 2.2 和 2.4 的结果中?看来2.3和2.5应该是mysql的文档描述的吧。

最佳答案

NOT IN 带有返回 NULL 的子查询应该总是返回 0 行。

相关:NOT IN clause and NULL values .


这看起来像是一个错误,并且在 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 Demo

关于mysql - 关于 mysql 的 IN 和 NOT IN 的危险,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52080492/

相关文章:

php - 如何在 MySQL 和 PHP 中编辑表值?

MySQL INSERT INTO SELECT 到一个带有 AUTO_INCREMENT 的表中

php - MySQL 具有大表和高访问权限 - 下一步升级是什么?

php - 通过谷歌地图 API 运行地址数据库?

MySQL:指复合键

php - Highcharts 和 JSON 问题

php - 查找哪些唯一数字被求和以产生结果数字

MySQL,如何选择两个值之和最小的行

php - 求和两个复杂的选择

mysql,加入和排除匹配