[英]Why can HAVING reference COUNT(column_name) but not the column_name itself?
I am trying to better understand how MySQL works.我试图更好地了解 MySQL 的工作原理。 I came across a problem with subgroups.我遇到了子组的问题。 From question Unknown column in 'having clause' , I understand why this code will return an error:从“有子句”中的问题未知列中,我理解了为什么这段代码会返回错误:
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%"
That error is: "Unknown column 'w.Author_id' in 'having clause'" because:该错误是:“‘有子句’中的未知列‘w.Author_id’”,因为:
The SQL standard requires that HAVING must reference only columns in the GROUP BY clause or columns used in aggregate functions. SQL 标准要求 HAVING 必须仅引用 GROUP BY 子句中的列或聚合函数中使用的列。 However, MySQL supports an extension to this behavior, and permits HAVING to refer to columns in the SELECT list and columns in outer subqueries as well.但是,MySQL 支持此行为的扩展,并允许 HAVING 引用 SELECT 列表中的列和外部子查询中的列。
But, if instead of w.Author_id = 1
, I use COUNT(w.Author_id) > 1
, the code exectues and works correctly:但是,如果我使用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%"
So, my question is: what is it about COUNT()
that makes w.Author_id
accessible?所以,我的问题是: COUNT()
是什么让w.Author_id
可以访问? I apologize if this is a silly/obvious question - I'm still a novice at SQL.如果这是一个愚蠢/明显的问题,我深表歉意——我还是 SQL 的新手。
The documentation seems pretty clear on this subject.关于这个主题的文档似乎很清楚。 But let me see if I can explain it better for you.但是让我看看我是否可以为你更好地解释它。
The HAVING
clause is essentially a WHERE
clause that "takes place" after the GROUP BY
. HAVING
子句本质上是在GROUP BY
之后“发生”的WHERE
子句。 That is, the aggregation has already happened, so the data that is available is the aggregated data.也就是说,聚合已经发生,所以可用的数据就是聚合数据。
In your example, there is no Author_Id
returned by the aggregation.在您的示例中,聚合没有返回Author_Id
。 And MySQL doesn't know how to generate one.而 MySQL 不知道如何生成一个。
However, COUNT(w.Author_Id)
is an aggregated result.但是, COUNT(w.Author_Id)
是聚合结果。 MySQL can just add that (conceptually) to the results returned by the aggregation and filter on it. MySQL 可以(从概念上)将其添加到聚合返回的结果中并对其进行过滤。
Your query is equivalent to:您的查询相当于:
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%';
That said, the query is better written as:也就是说,查询最好写成:
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;
You can filter on the title
before aggregating and that is usually much more efficient.您可以在聚合之前过滤title
,这通常效率更高。
When you put w.Author_id
in the expression COUNT(w.Author_id) > 1
you are satisfying the requirement for HAVING clause that当您将w.Author_id
放入表达式COUNT(w.Author_id) > 1
时,您就满足了 HAVING 子句的要求
HAVING must reference only columns in the GROUP BY clause or columns used in aggregate functions HAVING 必须仅引用 GROUP BY 子句中的列或聚合函数中使用的列
while the ID column alone won't, because it is not part of the GROUP BY
clause nor is within an aggregate function (which COUNT
is).而单独的 ID 列不会,因为它不是GROUP BY
子句的一部分,也不在聚合 function (其中COUNT
是)内。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.