我有2张桌子,作者和书籍
authors包含唯一ID idId
书籍也包含这个作为外键
我需要了解拥有最多书籍的作者。如果两位或多位作者并列最多的书籍,我需要向两位作者展示
我已经能够通过首先获得最大数量
来实现这一目标SELECT @maxCount := (MAX(counter)) FROM (SELECT count(*) AS counter FROM books GROUP BY authorId) AS counts;
然后使用它来获取具有该计数的ID作为我作者选择的一部分
SELECT *
FROM authors
WHERE authorId IN (
SELECT authorId
FROM books
GROUP BY authorId
HAVING COUNT(*) = @maxCount
);
我被告知我不允许使用变量,而且如果表格变得非常大,我所做的事情就非常低效。
我错过了一些明显的东西吗?有没有办法在没有变量(或临时表)的单个语句中执行此操作,而无需选择/分组整个书籍表两次?
答案 0 :(得分:2)
SELECT author, COUNT(*)
FROM authors
JOIN books
ON authors.authorId=books.AuthorId
GROUP BY author
ORDER BY COUNT(*) DESC
将根据每位作者的书籍数量为您提供一份清单。我附近没有一个实例可以测试,并且倾向于避开嵌入变量,但期望类似......
SELECT *
FROM (
SELECT author
, @maxcount:=IF(COUNT(*)>@maxcount,COUNT(*), @maxcount)
, COUNT(*) AS cnt
FROM authors
JOIN books
ON authors.authorId=books.AuthorId
GROUP BY author
ORDER BY COUNT(*) DESC
) ilv
WHERE cnt=@maxcount;
大型数据集的性能仍然很糟糕(即使使用正确的索引)。如果您必须经常使用> 100,000条记录运行此查询,那么您可以考虑对数据进行非规范化。
答案 1 :(得分:0)
Symcbean解决方案很棒...你可以为它添加限制1,只获得一个实例。
SELECT A.authorId, A.name, COUNT(*) AS num_books
FROM authors A
INER JOIN books B
ON A.authorId=B.AuthorId
GROUP BY A.authorId, A.name
ORDER BY COUNT(*) DESC
LIMIT 1
但是如果你想让所有分享最大书籍数量的作者,最好的办法是将max(count)存储在变量或临时表中,并在第二次查询中使用它。
例如,您可以将信息存储在以下临时表中CREATE TEMPORARY TABLE IF NOT EXISTS maxBooks AS (
SELECT authorId, COUNT(*) AS num_books
FROM books
GROUP BY authorId
ORDER BY COUNT(*) DESC
LIMIT 1
)
现在您可以将它加入到您的表中以获取等于最大计数的计数