【问题标题】:MySQL get players rank between datesMySQL获取日期之间的玩家排名
【发布时间】:2011-07-10 11:59:51
【问题描述】:

我有一张玩家桌:

id  points  last_online
 1     320  2011-07-10
 2    1025  2011-07-05
 3     750  2011-04-25
 4    5000  2011-07-10
 5     525  2011-05-01

为了获得玩家排名(基于积分),我有以下 mySQL 选择:

SELECT Player.*,
    ( SELECT COUNT(*)
      FROM players Player_i
      WHERE (Player_i.points, Player_i.id) >= (Player.points, Player.id)
     ) AS rank
FROM players AS Player
WHERE Player.id = 1

它工作正常。所以,玩家 ID 1 的排名是 5。

但我想只考虑过去 30 天内上次在线的玩家(考虑今天是 2011-07-10)。这样玩家 ID 1 的排名将是 3,因为玩家 3 和 5 被排除在排名之外。

知道我该怎么做吗?

【问题讨论】:

    标签: mysql sql rank


    【解决方案1】:

    两种方式。第一种方法,稍微编辑您的查询:

    SELECT Player.*,
        ( SELECT COUNT(*)
          FROM players Player_i
          WHERE Player_i.points >= Player.points
          and last_online > subdate(now(), '30 day')
         ) AS rank
    FROM players AS Player
    WHERE Player.id = 1
    and last_online > subdate(now(), '30 day'); -- EDITED to add this line
    

    第二种方法,也是更好的方法,是使用变量(性能更好,SQL更简单):

    set @rank := 0;
    SELECT *, @rank := @rank + 1
    FROM Player
    WHERE last_online > subdate(now(), 30 'day')
    ORDER BY points desc;
    

    【讨论】:

    • 我认为这是不正确的,因为它仍然会显示所有玩家——它只会省略最近没有在线的玩家的排名(或报告 0)。
    • 你是对的——我们有对方的另一半解决方案:)
    【解决方案2】:

    在您的查询中添加WHERE last_online > NOW() - '30 days'

    SELECT Player.*,
        ( SELECT COUNT(*)
        FROM players Player_i
        WHERE (Player_i.points, Player_i.id) >= (Player.points, Player.id)
            AND Player.last_online >= SUBDATE(NOW(), '30 day')
        ) AS rank
    FROM players AS Player
    WHERE Player.id = 1
        AND Player.last_online >= SUBDATE(NOW(), '30 day');
    

    【讨论】:

    • 我不这么认为...您的 SQL 是如何过滤一段时间未登录的人的?
    • @Bohemian:我不明白你的问题。 WHERE 子句的最后一行就是这样做的……
    • 但您还必须过滤子选择,不是吗?
    • @Bohemian:我不相信,所以,因为子选择在 WHERE 子句中使用 Player.id,所以它已经只考虑在外部选择中返回的值。
    • 实际上,当我考虑查询时,我相信它只会返回过去 30 天内在线的玩家,但它会将他们排在所有玩家中。所以是的,子选择也需要过滤——除非这是 OP 想要的行为:)
    猜你喜欢
    • 1970-01-01
    • 2017-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-09
    相关资源
    最近更新 更多