2010-05-05 74 views
3

我知道这是一个频繁的问题,但我无法弄清楚,我发现的例子并没有帮助。我所学到的最好的策略是尝试找到顶部范围的顶部和底部值,然后选择其余部分,但实施起来有点棘手。Top x rows and group by(again)

实施例的表:

id | title | group_id | votes 

我想获得的前3行投票从表中,为每个组。

我期待这样的结果:

91 | hello1 | 1 | 10 
28 | hello2 | 1 | 9 
73 | hello3 | 1 | 8 
84 | hello4 | 2 | 456 
58 | hello5 | 2 | 11 
56 | hello6 | 2 | 0 
17 | hello7 | 3 | 50 
78 | hello8 | 3 | 9 
99 | hello9 | 3 | 1 

我已经喜欢复杂的查询和例子,但他们并没有真正的帮助。

+0

你的问题有点令人困惑 - 你想要排名前3的投票行(我认为这意味着票数最多的前3行)?您的预期结果并不反映这一点(如果我的问题是准确的,456票应该是第一排,而不是第四排)。 – ABach 2010-05-05 19:58:44

+0

他希望每个'group_id'中的前3名投票获得者。 456是'group_id'的最高投票获得者2。 – 2010-05-05 19:59:53

+0

啊,我确定了... – ABach 2010-05-05 20:03:02

回答

3

您可以使用变量做到这一点:

SELECT 
    id, 
    title, 
    group_id, 
    votes 
FROM (
    SELECT 
     id, 
     title, 
     group_id, 
     votes, 
     @rn := CASE WHEN @prev = group_id THEN @rn + 1 ELSE 1 END AS rn, 
     @prev := group_id 
    FROM table1, (SELECT @prev := -1, @rn := 0) AS vars 
    ORDER BY group_id DESC, votes DESC 
) T1 
WHERE rn <= 3 
ORDER BY group_id, votes DESC 

这基本上是一样的,如支持ROW_NUMBER数据库以下查询:

SELECT 
    id, 
    title, 
    group_id, 
    votes 
FROM (
    SELECT 
     id, 
     title, 
     group_id, 
     votes, 
     ROW_NUMBER() OVER (PARTITION BY group_id ORDER BY votes DESC) AS rn 
    FROM student 
) T1 
WHERE rn <= 3 
ORDER BY group_id, votes DESC 

但由于MySQL不支持ROW_NUMBER还你必须模拟它,这就是变量的用途。这两个查询是相同的。试着先理解第二个查询,并希望第一个查询更有意义。

+0

非常感谢! 我按照你的指示,最后我明白了拳头的问题。 – 2010-05-05 21:20:13