根据分页总和获取用户排名

发布于 2024-12-28 17:11:52 字数 1200 浏览 0 评论 0原文

那里有几个排名帖子,但我还没有看到一个处理结果何时分页以及何时排名标准(在本例中:点)等于前一个用户的帖子。我尝试了一些预先存在的示例,但没有一个起作用。

我有一个名为“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);

我已阅读这些解决方案,但没有一个有效。

[Roland 的博客][1]

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

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

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

以及其他一些我可以链接的内容现在找不到。

有什么建议吗?

[编辑]

我使用了 ypercube 的底部答案。

There are several rank posts out there but I have yet to see one dealing with when the results are paginated and when the ranking criteria (in this case: points) is equal to the previous user. I have tried a few of the pre-existing examples but none have worked.

I have a table called "users" with the column "id". I also have a table called "points" with the columns "user_id" and "amount".

I need:

1.) Users with duplicate sum of points to have the same rank

Points Table

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

Rank should be

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

2.) Needs to maintain the ranking from one page to another so the rank has to be gathered in the query and not the resulting PHP.

3.) Display ALL users not just ones with rows in the points table because some users have 0 points and I want to display them last.

Right now I'm just listing the users in order of their points but their rank is not gathered because it wasn't working.

$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);

I've read these solutions and none have worked.

[Roland's Blog][1]

[How to get rank based on SUM's][2]

[MySQL, get users rank][3]

[How to get rank using mysql query][4]

and a few others whose link I can't find right now.

Any suggestions?

[EDIT]

I used ypercube's bottom answer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

负佳期 2025-01-04 17:11:52
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
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

But the above may be really slow with a big table and points awarded often. It might be really better to have just this and calculate the ranks in your application code:

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

This will work, too (edited, to work with the users table and with 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文