为什么 select NOT IN returns 0 row 而实际上有很多结果
Why select NOT IN returns 0 row while there are actually many results
如果我运行:
select ANY_VALUE(id)
from my_table
group by title
它将 return 5563 行,这些行都是具有不同 'title'.
的行的 ID
Table my_table 共有 6497 行。 (如果我 运行: Select * from my_table
我有 6497 行)
现在我希望这个查询能给我 my_table 中的其余 id(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;
全部return 0行。
我做错了什么?
我会说这是一个错误。
重现:
create table foo(id int auto_increment primary key, a int);
insert into foo(a) values(1), (1), (2);
当你执行 explain
和 show warnings
时(在 MySQL <= 5.6 中你必须执行 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
);
如果我运行:
select ANY_VALUE(id)
from my_table
group by title
它将 return 5563 行,这些行都是具有不同 'title'.
的行的 IDTable my_table 共有 6497 行。 (如果我 运行: Select * from my_table
我有 6497 行)
现在我希望这个查询能给我 my_table 中的其余 id(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;
全部return 0行。 我做错了什么?
我会说这是一个错误。
重现:
create table foo(id int auto_increment primary key, a int);
insert into foo(a) values(1), (1), (2);
当你执行 explain
和 show warnings
时(在 MySQL <= 5.6 中你必须执行 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
);