【问题标题】:MySQL Get Rank from LeaderboardsMySQL 从排行榜中获得排名
【发布时间】:2015-01-29 15:12:44
【问题描述】:

我正在根据非常好的教程在游戏中实现排行榜。

http://gamedevelopment.tutsplus.com/tutorials/how-to-code-a-self-hosted-phpsql-leaderboard-for-your-game--gamedev-11627

我对 MySQL 还很陌生,但我掌握了一些基础知识。但是有一部分代码我完全不知道实际上是如何工作的,因为我不想实现对我没有任何意义的东西我想问是否有人可以帮助我理解这一点。它处理返回玩家在排行榜中的排名:

SELECT  uo.*,
    (
    SELECT  COUNT(*)
    FROM    Scores ui
    WHERE   (ui.score, -ui.ts) >= (uo.score, -uo.ts)
    ) AS rank
FROM    Scores uo
WHERE   name = '$name';

我的理解是,首先选择 Scores 表中的所有内容,然后选择行数,我不明白该选择是如何工作的,WHERE 的工作方式完全超出了我的时间戳。然后我不确定它是如何一起工作的。

【问题讨论】:

    标签: mysql select leaderboard


    【解决方案1】:

    当数据库执行这个查询时,首先从Scores中选择,通过name = '$name'过滤。

    然后,对于每一行,它都会执行子查询:

    (
     SELECT  COUNT(*)
       FROM    Scores ui
      WHERE   (ui.score, -ui.ts) >= (uo.score, -uo.ts)
    ) AS rank
    

    这意味着,对于Scores的每一行,搜索名称,它会搜索Scores中有多少条记录,其中(ui.score, -ui.ts)大于或等于当前行的值。

    希望对你有所帮助...

    【讨论】:

    • 谢谢,这有点帮助。所以基本上只是重复你说的话:)它首先找到用户,获取他的数据( score 和 timeStamp ),然后将此数据与 Score 表中的所有其他数据进行比较,并计算其中有多少大于或等于用户的分数/时间戳并返回排名?这似乎是有道理的。如果可以请为我提供更多关于(ui.score,-ui.ts)> =(uo.score,-uo.ts)的信息。这对分数很有意义,但是负时间戳让我有点困惑。顺便说一句,这两个条件都需要满足吗?
    • 是的,这两个条件都需要满足。它在插入此行时计算所有更高的分数,因此未来的分数不会改变这个人的排名。它有一个 - 只是为了反转条件。
    • 哦,所以基本上新玩家添加的新分数不会影响玩家排名,因为他们是新人?嗯,这对我来说没有多大意义,我为什么要那样。有什么办法可以使排名始终按照其在排行榜中的实际最新位置正确更新? IE。在这种情况下,在我看来,如果有 10 名新玩家得分更高,我的排名仍然比他们高,因为我的分数发布得更早?无论何时发布分数,我都可以删除时间戳检查以确保我的排名正确吗?
    • 好吧,只需将条件更改为:(ui.score >= uo.score)
    • 太好了,非常感谢您的帮助。你让我免于在接下来的几个小时里摸不着头脑:)
    【解决方案2】:

    代数的一个事实是 -A >= -B if-and-only-if A

    所以表达式 (ui.score, -ui.ts) >= (uo.score, -uo.ts)

    只是检查 ui.score >= ui.score AND ui.ts

    包含时间戳的原因是有一个“决胜局”来唯一地定义排名。

    我不确定使用 (A, -B) >= (A2, -B2) 是否比仅编写 (A >= A2) AND (B

    【讨论】:

      猜你喜欢
      • 2018-12-20
      • 2014-05-24
      • 2018-01-31
      • 1970-01-01
      • 2019-03-22
      • 2020-05-26
      • 2016-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多