[英]Why can HAVING reference COUNT(column_name) but not the column_name itself?
我试图更好地了解 MySQL 的工作原理。 我遇到了子组的问题。 从“有子句”中的问题未知列中,我理解了为什么这段代码会返回错误:
SELECT b.Title, b.Isbn
FROM Book AS b
INNER JOIN Writing AS w ON w.Book_id = b.ID
GROUP BY b.ID
HAVING w.Author_id = 1 AND b.Title LIKE "%Head%"
该错误是:“‘有子句’中的未知列‘w.Author_id’”,因为:
SQL 标准要求 HAVING 必须仅引用 GROUP BY 子句中的列或聚合函数中使用的列。 但是,MySQL 支持此行为的扩展,并允许 HAVING 引用 SELECT 列表中的列和外部子查询中的列。
但是,如果我使用COUNT(w.Author_id) > 1
而不是w.Author_id = 1
,则代码执行并正常工作:
SELECT b.Title, b.Isbn
FROM Book AS b
INNER JOIN Writing AS w ON w.Book_id = b.ID
GROUP BY b.ID
HAVING COUNT(w.Author_id) > 1 AND b.Title LIKE "%Head%"
所以,我的问题是: COUNT()
是什么让w.Author_id
可以访问? 如果这是一个愚蠢/明显的问题,我深表歉意——我还是 SQL 的新手。
关于这个主题的文档似乎很清楚。 但是让我看看我是否可以为你更好地解释它。
HAVING
子句本质上是在GROUP BY
之后“发生”的WHERE
子句。 也就是说,聚合已经发生,所以可用的数据就是聚合数据。
在您的示例中,聚合没有返回Author_Id
。 而 MySQL 不知道如何生成一个。
但是, COUNT(w.Author_Id)
是聚合结果。 MySQL 可以(从概念上)将其添加到聚合返回的结果中并对其进行过滤。
您的查询相当于:
SELECT Title, Isbn
FROM (SELECT b.Title, b.Isbn, COUNT(*) as cnt
FROM Book b JOIN
Writing w
ON w.Book_id = b.ID
GROUP BY b.ID
) b
WHERE cnt > 1 AND b.Title LIKE '%Head%';
也就是说,查询最好写成:
SELECT b.Title, b.Isbn
FROM Book b JOIN
Writing w
ON w.Book_id = b.ID
WHERE b.Title LIKE '%Head%'
GROUP BY b.ID
HAVING COUNT(*) > 1;
您可以在聚合之前过滤title
,这通常效率更高。
当您将w.Author_id
放入表达式COUNT(w.Author_id) > 1
时,您就满足了 HAVING 子句的要求
HAVING 必须仅引用 GROUP BY 子句中的列或聚合函数中使用的列
而单独的 ID 列不会,因为它不是GROUP BY
子句的一部分,也不在聚合 function (其中COUNT
是)内。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.