2010-01-22 39 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