为什么可以使用引用计数(列名称)而不是列名称本身?

f87krz0w  于 2021-08-13  发布在  Java
关注(0)|答案(2)|浏览(347)

我试图更好地理解mysql的工作原理。我遇到了一个关于小组的问题。从“having子句”中的“question unknown”列中,我了解此代码将返回错误的原因:

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%"

该错误是:“having子句”中的未知列“w.author\u id”,因为:
sql标准要求having必须只引用groupby子句中的列或聚合函数中使用的列。但是,mysql支持对这种行为的扩展,并允许引用select列表中的列和外部子查询中的列。
但是,如果 w.Author_id = 1 ,我用 COUNT(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的新手。

vyswwuz2

vyswwuz21#

关于这个问题的文件似乎很清楚。但让我看看能不能给你更好的解释。
这个 HAVING 子句本质上是一个 WHERE “发生”在 GROUP BY . 也就是说,聚合已经发生,所以可用的数据就是聚合的数据。
在你的例子中,没有 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 在聚合之前,这通常效率更高。

lnlaulya

lnlaulya2#

当你把 w.Author_id 在表达式中 COUNT(w.Author_id) > 1 你是在满足你的要求
having必须只引用groupby子句中的列或聚合函数中使用的列
而id列本身不会,因为它不是 GROUP BY 子句nor位于聚合函数(其中 COUNT 是)。

相关问题