为什么在此SQL查询中为什么'='不起作用?

时间:2019-09-29 15:58:18

标签: mysql sql

我有一个针对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级。

3 个答案:

答案 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