繁体   English   中英

为什么 HAVING 可以引用 COUNT(column_name) 而不能引用 column_name 本身?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM