我有两个表,Writer和Books。作家可以制作许多书籍。我希望得到产生最多书籍的所有作家。
首先,我的SQL查询如下:
SELECT Name FROM(
SELECT Writer.Name,COUNT(Book.ID) AS NUMBER FROM Writer,Book
WHERE
Writer.ID=Book.ID
GROUP BY Writer.Name
)
WHERE NUMBER=(SELECT MAX(NUMBER) FROM
(SELECT Writer.Name,COUNT(Book.ID) AS NUMBER FROM Writer,Book
WHERE Writer.ID=Book.ID
GROUP BY Writer.Name
)
有效。但是我觉得这个查询太长了,并且存在一些重复。我想让这个查询更短。所以我尝试这样的另一个查询:
SELECT Name FROM(
SELECT Writer.Name,COUNT(Book.ID) AS NUMBER FROM Writer,Book
WHERE
Writer.ID=Book.ID
GROUP BY Writer.Name
HAVING NUMBER = MAX(NUMBER)
)
然而,这个HAVING子句不起作用,我的sqlite说它是一个错误。 我不知道为什么。有谁可以向我解释一下?谢谢!
答案 0 :(得分:3)
HAVING
子句提供对最终集的过滤(通常在分组之后),并且不提供其他分组功能。可以将它想象为WHERE子句,但可以在GROUP BY
之后应用。
您使用HAVING NUMBER = MAX(NUMBER)
的查询意味着在所有记录中对NUMBER值组进行分组,并且在此示例中没有意义(即使我们都得到了您希望它执行的操作)。
答案 1 :(得分:1)
在MySQL(但不是SQLite)中,您可以使用变量来减少工作量并进行更简单的查询。但是,那里有细微差别,因为group by
变量需要额外级别的子查询:
SELECT name
FROM (SELECT t.*, (@m := if(@m = 0, NUMBER, @m)) as maxn
FROM (SELECT w.Name, COUNT(b.ID) AS NUMBER
FROM Writer w JOIN
Book b
ON w.ID = b.ID
GROUP BY w.Name
) t CROSS JOIN
(SELECT @m := 0) params
ORDER BY NUMBER desc
) t
WHERE maxn = number;
答案 2 :(得分:1)
每个查询都为您提供一个级别的聚合,因此您无法在同一查询中Max
上使用COUNT
。您需要像在第一次查询中一样进行子查询。
但是,您的第一个查询可以在MySQL上简化为:
SELECT Writer.Name
FROM Writer, Book
WHERE Writer.ID = Book.ID
GROUP BY Writer.Name
HAVING COUNT(Book.ID) = (SELECT COUNT(Book.ID) AS n
FROM Writer, Book
WHERE Writer.ID = Book.ID
GROUP BY Writer.Name
ORDER BY n DESC
LIMIT 1)
答案 3 :(得分:0)
看起来你正在嵌套聚合函数,这是不允许的。
HAVING NUMBER = MAX(NUMBER)就像HAVING COUNT(Book.ID)= MAX(COUNT(Book.ID))
在MAX中嵌入COUNT似乎是这里的问题