2010-01-22 64 views
3

您好世界各地的程序員,MySQL的「排名在排行榜」 -Query

我工作的一個項目中,用戶可以爲它做某些事情,並獲得積分。爲了簡化這個問題,我們假設我們有兩個表用戶

-- table user  -- table points 
+---------------+ +-----------------------------+ 
| id | name | | id | points | user_id | 
+---------------+ +-----------------------------+ 
| 1  Tim | | 1  5   1  | 
| 2  Tom | | 2  10   1  | 
| 3  Marc | | 3  5   1  | 
| 4  Tina | | 4  12   2  | 
| 5  Lutz | | 5  2   2  | 
+---------------+ | 6  7   1  | 
        | 7  40   3  | 
        | 8  100  1  | 
        +-----------------------------+ 

我們得到完整的高分列表我用下面的查詢

SELECT u.*, SUM(p.points) AS sum_points 
FROM user u 
LEFT JOIN points p ON p.user_id = u.id 
GROUP BY u.id 
ORDER BY sum_points DESC 

導致細高分名單與第一所有用戶持續

+------------------------------+ 
| id | name | sum_points | 
+------------------------------+ 
| 1  Tim  127   | 
| 3  Marc  40   | 
| 2  Tom  14   | 
| 4  Tina  0   | 
| 5  Lutz  0   | 
+------------------------------+ 

好吧回到問題本身。在單個用戶的個人資料上,我想在高分列表中顯示他的排名。

這可以通過使用單個查詢來完成,只需顯示例如Tom(id = 2)排名在第3位?

非常感謝:-)

回答

4

的想法是要問, 「有多少玩家級以上@this_user」:

select count(*) + 1 from 
(
    /* list of all users */ 
    SELECT SUM(p.points) AS sum_points 
    FROM user u 
    LEFT JOIN points p ON p.user_id = u.id 
    GROUP BY u.id   
) x 
/* just count the ones with higher sum_points */ 
where sum_points > (select sum(points) from points where user_id = @this_user) 

編輯做的結果,而不是基於1 0-based

+1

+1,這是什麼我一直在努力,但你首先得到了它。有一件事要注意 - 爲了得到用戶的位置,它會是count(*)+1(正如你所說的,這隻會得到高於@this_user分數的用戶數)。 – rosscj2533 2010-01-22 16:14:41

+0

@ rosscj2533:謝謝,修正。 – egrunin 2010-01-22 19:50:13

1
SELECT q.*, 
     @r := @r + 1 AS rank 
FROM (
     SELECT @r := 0 
     ) vars, 
     (
     SELECT u.*, 
       SUM(p.points) AS sum_points 
     FROM 
       user u 
     LEFT JOIN 
       points p 
     ON  p.user_id = u.id 
     GROUP BY 
       u.id 
     ORDER BY 
       sum_points DESC 
     ) q 
+0

這不完全是我要求的,但也真的有幫助:) – Flatlin3 2010-01-22 16:29:17

+0

'@ Tim':哦,對不起,現在得到:) – Quassnoi 2010-01-22 16:30:10