MySQL 连接表的最大 N 个结果

MySQL Greatest N Results with Join Tables

选择前 n 个结果,我在这里看到了很多关于如何做到这一点的帖子和精彩文章,但我很难用我的数据集来做到这一点。大多数示例都集中在数据集上,而不需要额外的连接。

我一直在尝试将 http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/ 中的示例应用到我的查询中,但没有成功。

Person、Credit、Media 三个表。

Person 链接到 Credit 和 Credit to Media。

下面的查询应该 return 每个人的前 5 个媒体,但它不是,我哪里错了?

SELECT 
p.id AS person_id, 
c.id AS credit_id, 
m.id AS media_id, m.rating_average
FROM person p
INNER JOIN credit c ON c.person_id = p.id
INNER JOIN media m ON m.id = c.media_id
where (
   select count(*) from media as m2
    inner JOIN credit c2 on m2.id=c2.media_id
   where c2.person_id = c.person_id and m2.rating_average >= m.rating_average
) <= 5

澄清:

顶级媒体是根据 rating_average 最高的媒体计算得出的。

更新:

SQLFiddle http://sqlfiddle.com/#!9/eb0fd

每人 (p) 前 3 个媒体 (m) 的期望输出。显然我想为前 5 名媒体做到这一点,但这只是测试数据。

p   m   c   rating_average
1   9   27  9
1   7   28  8
1   1   1   8
2   1   5   8
2   4   8   8
2   7   29  8
3   4   10  8
3   3   9   6
3   5   11  5
4   3   13  6
4   5   14  5
4   6   15  3
5   4   16  8
5   5   17  5
5   6   18  3
6   6   19  3
7   7   20  8
8   9   23  9
8   1   21  8
8   8   22  0
9   1   24  8
9   7   26  8
9   5   25  5

我想我解决了:)

首先,这是一个基于您开始方式的解决方案。但是有一个问题我无法解决它以显示每个 person_id 的确切 3(或者你选择的任何数字,例如我选择 3)行。问题是解决方案是基于计算 rating_average 大于当前行的行数。因此,如果您有 5 个相同的最高值,您可以选择显示所有 5 个或根本不显示它们,这并不好。所以这就是你这样做的方式......(当然这是一个例子,如果你有 4 个最高值,你会把它们全部显示出来(我认为不显示数据根本没有意义))...

 SELECT t1.person_id, t1.credit_id, t1.media_id, t1.rating_average
 FROM (SELECT p.id AS person_id, c.id AS credit_id, m.id AS media_id, 
              m.rating_average AS rating_average
       FROM person p
       INNER JOIN credit c ON c.person_id = p.id
       INNER JOIN media m ON m.id = c.media_id) as t1
 WHERE (SELECT COUNT(*) 
       FROM (SELECT p.id AS person_id, c.id AS credit_id, m.id AS media_id, 
                    m.rating_average AS rating_average
             FROM person p
             INNER JOIN credit c ON c.person_id = p.id
             INNER JOIN media m ON m.id = c.media_id) AS t2
       WHERE t2.person_id = t1.person_id AND t2.rating_average > t1.rating_average) < 3
 ORDER BY person_id ASC, rating_average DESC

重要提示: 如果您没有自我重复的价值,此解决方案可以工作(为每个人显示确切的 3 行)...这是 Fiddle http://sqlfiddle.com/#!9/eb0fd/64 你可以看到 person_id 是 1!

的问题

在那之后我又玩了一点,让它在我想的问题中按照你想要的方式工作。这是一个代码:

SET @num := 0, @person := 0;

SELECT person_id, credit_id, media_id, rating_average, rowNumber 
FROM (SELECT t1.person_id, t1.credit_id, t1.media_id, t1.rating_average,
             @num := if(@person = t1.person_id, @num + 1, 1) AS rowNumber,
             @person := t1.person_id
      FROM (SELECT p.id AS person_id, c.id AS credit_id, m.id AS media_id, 
                   m.rating_average AS rating_average
            FROM person p
            INNER JOIN credit c ON c.person_id = p.id
            INNER JOIN media m ON m.id = c.media_id
            ORDER BY p.id ASC, m.rating_average DESC) as t1) as t2
 WHERE rowNumber <= 3

这是 Fiddle http://sqlfiddle.com/#!9/eb0fd/65 ...

GL!

P. S. 对不起我的英语希望你能理解我在说什么...