MySQL - 如何在排序后获取行号?

11

假设我有一个具有以下列的表:


p_id

userid

points


假设这些列有超过5000条记录。因此,我们实际上拥有具有积分的用户。每个用户都有一个唯一的行来记录他们的积分。想象一下,每个用户都可以通过在网站上点击某个地方来获得积分。当他们点击时,我会更新数据库以记录他们获得的积分。

因此,我们有一个包含5000多个人拥有积分的记录的表,对吧?现在我想按照他们的积分(降序)对它们进行排序,这样如果我运行一个MySQL查询,积分最高的用户将会出现在页面顶部。

我可以通过简单地运行像这样的查询来实现:

SELECT `p_id` FROM `point_table` ORDER BY `points` DESC

这个查询可以按点数降序返回所有记录。

好的,我的问题来了,现在(当它排序了),我想显示每个用户实际上是排名第几。所以我想给每个用户类似于这样的东西:“您是5374个用户中的第623个”。问题是我无法指定这个“623”数字。

我想运行一个查询,它应该按点数对表进行排序,然后“搜索”或计算行号,找出他们的记录在哪里,然后将该值返回给我。

有谁能帮我建立这个查询吗?这将是一次真正的大帮助。谢谢。


下面的答案无法正常工作,因为order by将在选择变量之后进行评估。请参见https://dev59.com/7HE85IYBdhLWcg3w9orw#29846430中的警告。 - Pacerier
4个回答

16

这个答案 对您应该有帮助:

SET @rank=0;
SELECT @rank:=@rank+1 AS rank, p_id FROM point_table ORDER BY points DESC;

更新:在更新积分并将其保存到同一表中的其他列时,您可能还希望考虑计算排名。这样,您还可以选择单个用户并知道他的排名。根据您的使用情况,哪种方法更有意义且执行效果更好取决于。

更新:我们在评论中讨论出的最终解决方案如下:

SELECT
rank, p_id
FROM
    (SELECT
     @rank:=@rank+1 AS rank, p_id, userid
     FROM
     point_table, (SELECT @rank := 0) r
     ORDER BY points DESC
    ) t
WHERE userid = intval($sessionuserid); 

1
实际上对我来说并没有起作用,因为它总是给我“1”,而在我的情况下正确的数字应该是2。你还忘了仅选择特定用户的行。 - user1406071
1
mysql_query("SET @rank=0;"); 返回mysql_query("SELECT @rank:=@rank+1 AS rank, p_id FROM point_table WHERE userid = $sessionuserid ORDER BY points DESC"); - user1406071
1
那么,没有这样的查询,比如我对表中的数据进行排序,然后给它们一个行号,并选择其中userid = userid的特定行号吗?没有这样的东西吗?:OO 那将非常有趣。 - user1406071
2
谢谢,但实际上它并没有起作用 :/ 顺便问一下,那里的“r”和“t”是什么意思? - user1406071
抱歉,再试一次:SELECT rank, p_id FROM (SELECT @rank:=@rank+1 AS rank, p_id, userid FROM point_table, (SELECT @rank := 0) r ORDER BY points DESC) t WHERE userid = intval($sessionuserid); - sprain
显示剩余7条评论

6

在使用“order by”排序之后的行数

SELECT ( @rank:=@rank + 1) AS rank, m.* from                                   
(                            
  SELECT a.p_id, a.userid                                                   
  FROM (SELECT @rank := 0) r, point_table a 
  ORDER BY a.points DESC                                                     
) m

0

由于某些原因,被接受的答案对我来说不起作用 - 它完全忽略了“ORDER BY”语句,按id(主键)排序

我所做的是:

SET @rn=0;
CREATE TEMPORARY TABLE tmp SELECT * FROM point_table ORDER BY points DESC;
SELECT @rn:=@rn+1 AS rank, tmp.* FROM tmp;

-1

在表中添加一个新的position列。定期运行一个cron job,该任务通过按照points字段对所有表行进行排序,并使用while循环更新表中的位置。


我实际上并不想向表发送太多更新。因为如果我有100,000个成员,其中20,000个成员每秒更新一次数据库,那将是一场灾难。这就是为什么我只想通过查询获取它们的排名。我不会对其进行任何其他操作,只需要排名。 - user1406071
我认为这就是stackoverflow所做的。他们不会每秒都这样做,而是每天一次。浏览器游戏排名也是如此。 - yunzen
嗯,你认为这比在一个查询中运行两个查询更好/更快吗? - user1406071
应该是一样的。不同之处在于,这里你只需要做一次,而那里你需要一直做。 - yunzen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接