一个表中最常出现在另一个表中的MYSQL条目

时间:2017-12-04 21:55:42

标签: mysql sql

我有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
);

我被告知我不允许使用变量,而且如果表格变得非常大,我所做的事情就非常低效。

我错过了一些明显的东西吗?有没有办法在没有变量(或临时表)的单个语句中执行此操作,而无需选择/分组整个书籍表两次?

2 个答案:

答案 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
)

现在您可以将它加入到您的表中以获取等于最大计数的计数