2010-05-05 77 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