以下查询工作正常。我使用外部选择中的值来过滤内部选择。
SELECT
bk.ID,
(SELECT COUNT(*) FROM guests WHERE BookingID = bk.ID) as count
FROM
bookings bk;
但是,以下选择不起作用:
SELECT
bk.ID,
(SELECT SUM(count) FROM (SELECT COUNT(*) AS count FROM guests WHERE BookingID = bk.ID GROUP BY RoomID) sub) as sumcount
FROM
bookings bk;
错误消息为:Error Code: 1054. Unknown column 'bk.ID' in 'where clause'
为什么我的别名bk
在子选择中已知,但在子选择的子选择中却不知道?
为了记录,我使用的是MySQL 5.6。
答案 0 :(得分:3)
SELECT列表中的相关标量子查询通常可以重写为派生表上的LEFT JOIN(在许多情况下,它们可能会表现得更好):
SELECT
bk.ID,
dt.sumcount
FROM
bookings bk
LEFT JOIN
(SELECT BookingID,SUM(COUNT) AS sumcount
FROM
(
SELECT BookingID, RoomId, COUNT(*) AS COUNT
FROM guests
GROUP BY BookingID, RoomID
) sub
) AS dt
ON bk.BookingID = dt.BookingID
答案 1 :(得分:2)
这被称为"范围"。我知道Oracle(例如)只查找一个级别来解析表别名。 SQL Server也是一致的:它看起来不止一个层次。
基于此示例,MySQL明确将标识符bk
的范围限制为直接子查询。在documentation(强调我的)中有一个小提示:
相关子查询是包含对a的引用的子查询 表格也出现在 外部查询中。
但是,我没有在文档中找到任何其他具体的参考范围规则。还有其他答案(here和here)指定表别名的范围仅限于一个子查询级别。
您已经知道如何解决问题(您的两个查询应该产生相同的结果)。重新安排查询以具有联接和聚合也可以解决此问题。