【问题标题】:MySQL Rank Not Matching High Score in TableMySQL Rank 与表中的高分不匹配
【发布时间】:2013-06-28 19:53:11
【问题描述】:

在制作游戏时,获取前 10 名的 MySQL 调用如下:

SELECT username, score FROM userinfo ORDER BY score DESC LIMIT 10

这似乎工作得很好,但是当与调用以获得单个玩家的排名配对时,如果玩家与其他玩家的分数相同,则数字可能会有所不同。获取玩家排名的调用如下:

SELECT (SELECT COUNT(*) FROM userinfo ui WHERE (ui.score, ui.username) >= (uo.score, uo.username)) AS rank FROM userinfo uo WHERE username='boddie';

第一次调用的示例结果:

+------------+-------+
| username   | score |
+------------+-------+
| admin      |  4878 |
| test3      |  3456 |
| char       |   785 |
| test2      |   456 |
| test1      |   253 |
| test4      |    78 |
| test7      |     0 |
| boddie     |     0 |
| Lz         |     0 |
| char1      |     0 |
+------------+-------+

第二次调用的示例结果

+------+
| rank |
+------+
|   10 |
+------+

可以看出,第一次调用将玩家排在列表中的第 8 位,但第二次调用将他排在第 10 位。要进行哪些更改或我可以做些什么来使这些调用产生匹配的结果?

提前感谢您的帮助!

【问题讨论】:

  • 你有效地按分数 desc 和用户名 desc 排序,因此 boddie 低于 Lz 和 char1
  • 是的,在查看了以下所有出色的回复后,我开始看到错误。好东西太多了哈哈

标签: mysql leaderboard scoring


【解决方案1】:

我会更改您的 Order by 以包含用户名,以便您始终获得相同的订单。所以它看起来像:

... ORDER BY score DESC, username ASC ...

【讨论】:

    【解决方案2】:

    您需要在第一个查询中:

    ORDER BY 
       score DESC,
       username DESC
    

    这样它会达到第 10 位...这是由于第二个查询中的用户名比较:

    (ui.score, ui.username) >= (uo.score, uo.username)

    【讨论】:

    • 赞成,因为我们在同一分钟内得到了几乎相同的答案,但可能希望名称按字母升序排列,而不是降序排列 :)
    • @BryPie 您可以通过更改第二个查询来做到这一点
    • 由于简单性而最终使用了它,并且它与我所拥有的相当好。谢谢!
    【解决方案3】:
    SELECT
        uo.username,
        (SELECT COUNT(*)+1 FROM userinfo ui WHERE ui.score>uo.score) AS rank
    FROM userinfo uo
    WHERE uo.username='boddie'
    

    或者如果您需要获取用户名、分数和排名:

    SELECT
        uo.username,
        uo.score,
        (@row := @row + 1) AS rank
    FROM userinfo uo
    JOIN (SELECT @row := 0) r
    ORDER BY uo.score DESC, uo.username ASC
    

    你可以添加

    HAVING uo.username = 'boddie'
    

    只获得一个用户

    【讨论】:

    • 在你的情况下,所有得分 = 0 的用户都将拥有相同的排名:)
    • 是的,但你需要一种方法来区分它们,就像 OP 尝试过的那样
    • 不确定使用 HAVING 作为第二个答案是否安全,因为 MySQL 可以选择使用用户变量优化查询的可能方式
    【解决方案4】:

    另一种方法:-

    SELECT UsersRank
    FROM 
    (
        SELECT userinfo.score, userinfo.username, @Rank:=@Rank+1 AS UsersRank
        FROM userinfo 
        CROSS JOIN (SELECT (@Rank:=0)) Sub1
        ORDER BY userinfo.score DESC, userinfo.username
    ) Sub2
    WHERE username = 'boddie'
    

    【讨论】:

      【解决方案5】:

      试试这个。

      SELECT (COUNT(*)+1) AS rank
      FROM   userinfo ui
      WHERE  ui.score > (SELECT score
                         FROM   userinfo
                         WHERE  username='boddie');
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-01
        • 1970-01-01
        • 2011-12-03
        相关资源
        最近更新 更多