我有一个针对MySQL 8中sakila数据库的查询(您可以从https://hub.docker.com/r/1maa/sakila轻松设置一个)。
select * from store _0 where (
select address_id from (
select * from address _3 where (
address_id = (
select address_id from (
select * from store _1
where store_id=_0.store_id
) _2
)
)
) _4
);
此查询返回一个空表。
但是,当我重写最内层
select address_id from (
select * from store _1
where store_id=_0.store_id
) _2
进入:
select address_id from store _1
where store_id=_0.store_id
,它将返回store
表中的所有2行,这是我期望的。
这是为什么?看来我只是将两步选择简化为1。
我还注意到,如果在in
条件下使用=
而不是address_id = ..
,我可以获得预期的结果。
这背后的理论是什么?
由于生成查询,该查询过于复杂。因此,感谢您对简化查询的建议,但我只想知道为什么它不能给出正确的结果。
并且必须具有MySQL 8.0.14及更高版本才能重现它,因为早期版本不允许别名超过1级。
答案 0 :(得分:1)
之所以需要一个in子句,是因为sub select返回多个结果。
您是否只是试图将两个表连接在一起?为什么不使用联接而不是子选择呢?
SELECT s.*
FROM store s
JOIN address a
ON a.address_id = s.address_id
答案 1 :(得分:0)
select address_id from (
select * from store _1
where store_id=_0.store_id
) _2
在第一个代码段中,您从商店_1中选择与商店_0具有相同store_id条目的列。如果比较语句返回true,则从这些列中检索到address_id,但是如果这些列中没有存储address_id条目怎么办?
select address_id from store _1
where store_id=_0.store_id
在第二个代码段中,您将从商店_1中选择address_id,其中商店_0和_1的store_id的比较返回true。在商店_1中选择address_id的范围比在第一个代码段中的选择范围更广,因此可以检索到address_id。
TL; DR不同的结果与您的搜索范围和关系数据库中的数据结构有关!
答案 2 :(得分:0)
我将此报告给MySQL。确认这是一个优化程序错误:https://bugs.mysql.com/bug.php?id=97063。