获得基于分页总和的用户排名

时间:2012-01-24 15:41:15

标签: mysql sum rank

有几个排名帖子,但我还没有看到一个处理结果何时被分页以及排名标准(在这种情况下:点数)等于前一个用户。我已经尝试了一些预先存在的例子但没有一个有效。

我有一个名为“users”的表,其列为“id”。我还有一个名为“points”的表,其中包含“user_id”和“amount”列。

我需要:

1。)具有重复点数的用户具有相同的等级

积分表

user_id     amount
   1          10
   2          20
   1           5
   3          20
   3          -5
   4          5

排名应

rank     user_id    total
 1          2        20
 2          1        15
 2          3        15
 3          4        5

2.。)需要将排名从一个页面维护到另一个页面,因此必须在查询中收集排名,而不是生成的PHP。

3.。)显示所有用户不仅仅是点数表中有行的用户,因为有些用户有0分,我想最后显示它们。

现在我只是按照他们的积分排列用户,但是他们的排名没有收集,因为它不起作用。

$getfanspoints = mysql_query("SELECT DISTINCT id,
(SELECT SUM(amount) AS points FROM points WHERE points.user_id = users.id) AS points
FROM users
ORDER BY points DESC LIMIT $offset, $fans_limit", $conn);

我已经阅读过这些解决方案而且都没有。

[罗兰的博客] [1]

[如何根据SUM的等级获得排名] [2]

[MySQL,获得用户排名] [3]

[如何使用mysql查询获得排名] [4]

和其他一些我现在找不到的链接。

有什么建议吗?

[编辑]

我使用了ypercube的底部答案。

1 个答案:

答案 0 :(得分:1)

SELECT COUNT(*) AS rank
     , t.user_id
     , t.total 
FROM
      ( SELECT   user_id
             ,   SUM(amount) AS total
        FROM     points 
        GROUP BY user_id
      ) AS t
  JOIN
      ( SELECT DISTINCT
                 SUM(amount) AS total
        FROM     points 
        GROUP BY user_id
      ) AS dt
    ON 
        t.total <= dt.total
GROUP BY t.user_id
ORDER BY rank
       , user_id

但是上面的表格可能会非常慢,并且经常会获得积分。拥有这个并计算应用程序代码中的排名可能真的更好:

SELECT   users.id    AS user_id
     ,   SUM(amount) AS total
FROM     
         users
  LEFT JOIN
         points
    ON   points.user_id = users.id
GROUP BY users.id
ORDER BY total DESC
       , user_id

这也可以(编辑后,与users表和OFFSET一起使用):

SELECT *
FROM
  ( SELECT
          @rank := @rank + (@t <> total) AS rank
        , user_id 
        , @t := total AS total
    FROM 
        ( SELECT   users.id AS user_id
               ,   COALESCE(SUM(amount),0) AS total
          FROM users
            LEFT JOIN points
              ON users.id = points.user_id
          GROUP BY users.id
        ) AS o
      CROSS JOIN
        ( SELECT @rank := 0, @t := -999999
        ) AS dummy
    ORDER BY total DESC
           , user_id
  ) tmp
LIMIT x OFFSET y