为啥选择 NOT IN 返回 0 行,而实际上有很多结果
Posted
技术标签:
【中文标题】为啥选择 NOT IN 返回 0 行,而实际上有很多结果【英文标题】:Why select NOT IN returns 0 row while there are actually many results为什么选择 NOT IN 返回 0 行,而实际上有很多结果 【发布时间】:2020-03-04 12:18:54 【问题描述】:如果我跑:
select ANY_VALUE(id)
from my_table
group by title
它将返回 5563 行,这些行都是具有不同“标题”的行的 id。
表 my_table 共有 6497 行。 (如果我运行:Select * from my_table
我有 6497 行)
现在我希望这个查询会给我 my_table 中 id(s) 的其余(934 行)列表:
Select * from my_table where id NOT IN (
select ANY_VALUE(id)
from my_table
group by title)
但它给了我 0 行。
我也试过了:
Select * from my_table where id NOT IN (
select ANY_VALUE(id)
from my_table
group by title) AND id IS NOT NULL
或
Select * from my_table where not exists (
select ANY_VALUE(id) AS value
from my_table
group by title) and id is not NULL;
它们都返回 0 行。 我做错了什么?
【问题讨论】:
调查:fiddle. 您必须记住ANY_VALUE()
是非确定性函数。所以除了输出表达式列表外不能使用。
为什么不直接使用MAX
或MIN
函数呢?在这种情况下会做同样的工作。
【参考方案1】:
我会说这是一个错误。
复制:
create table foo(id int auto_increment primary key, a int);
insert into foo(a) values(1), (1), (2);
当您执行 explain
和 show warnings
(在 mysql explain extended)时,您可以看到优化器完成工作后 MySQL 实际执行的操作:
mysql > explain select * from foo where id not in (select id from foo group by a);
+----+--------------------+-------+------------+-----------------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------------+-------+------------+-----------------+---------------+---------+---------+------+------+----------+-------------+
| 1 | PRIMARY | foo | NULL | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | Using where |
| 2 | DEPENDENT SUBQUERY | foo | NULL | unique_subquery | PRIMARY | PRIMARY | 4 | func | 1 | 100.00 | NULL |
+----+--------------------+-------+------------+-----------------+---------------+---------+---------+------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
mysql > show warnings;
+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Note | 1003 | /* select#1 */ select `playground`.`foo`.`id` AS `id`,`playground`.`foo`.`a` AS `a` from `playground`.`foo` where (not(<in_optimizer>(`playground`.`foo`.`id`,<exists>(<primary_index_lookup>(<cache>(`playground`.`foo`.`id`) in foo on PRIMARY))))) |
+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
如您所见,这是一个完全不同的查询。不再分组。要获得您期望的结果,您必须再嵌套一次查询,如下所示:
select * from foo where id not in (
select id from (
select any_value(id) as id from foo group by a
) sq
);
【讨论】:
谢谢,您的最后一个查询确实给出了预期的结果。虽然我不清楚你的解释,但它是我的解决方案。以上是关于为啥选择 NOT IN 返回 0 行,而实际上有很多结果的主要内容,如果未能解决你的问题,请参考以下文章
为啥我得到“[__NSArrayI allKeys]:无法识别的选择器发送到实例”/为啥 NSDictionary 正在转换?