Mysql在“sum”和“group”之后得到行的位置

时间:2016-12-07 17:56:51

标签: mysql sql

我需要在total_points上以两种不同的方式获取此表中单个玩家ID的位置(除非可以在1中完成,否则2个单独的查询是正常的吗?)

例如,如果 player_id = 1 - 我需要通过两种方式从总分中找出他们的行位置:

  1. 在player_id上分组和SUM(包括所有season_id和guild_id)
  2. 将player_id与一个特定的season_id组合在一起并使用SUM(包括所有guild_id)
  3. +-----------+-----------+----------+--------------+
    | player_id | season_id | guild_id | total_points |
    +-----------+-----------+----------+--------------+
    |         1 |         1 |        1 |            5 |
    |         2 |         1 |        2 |            6 |
    |         3 |         2 |        1 |            2 |
    ....
    |         1 |         1 |        2 |            4 |
    |         2 |         2 |        2 |            4 |
    |         4 |         1 |        3 |            8 |
    +-----------+-----------+----------+--------------+
    

    所以在这个例子中我会说 player_id = 1 ,结果将返回到我的位置2,因为他们有第二个最高的SUM total_points,在这个例子中是9(玩家2有10)。

    在另一个查询中,我需要在season_id中对结果进行分组。 player_id = 1和season_id = 1应该返回位置1,因为他们有9,这是本赛季中最高的。

    我稍后还需要通过guild_id限制它,但我想如果我得到一个使用player_id和season_id的查询

    我可以解决这个问题

    任何帮助都会很棒所以我不需要在PHP内部完成所有这些操作并迭代所有数据库结果,如果可以在MySQL中完成,这会浪费资源,因为这个表最终会有数百万条记录

    谢谢。

2 个答案:

答案 0 :(得分:2)

我不确定它是否可以短得多,但以下查询应该提供您要求的内容:

SELECT rank
FROM (
    SELECT player_id, total_sum, @rank:=@rank+1 AS rank 
    FROM (
        SELECT player_id,  SUM(total_points) AS total_sum
        FROM players
        WHERE season_id=1 -- if you don't want to filter by season, remove this; or add more if you want to filter by other columns
        GROUP BY player_id
        ORDER BY total_sum DESC) AS sq, 
        (SELECT @rank:=0) AS tr
) AS q WHERE player_id = 1;

查询说明

在最深的子查询中,您可以计算所需数据的总点数之和:

SELECT player_id,  SUM(total_points) AS total_sum
FROM players
WHERE season_id=1 -- if you don't want to filter by season, remove this; or add more if you want to filter by other columns
GROUP BY player_id
ORDER BY total_sum DESC

您可以省略WHERE或添加更多条件。最后一行显示您按总和下降顺序,给出最高的第一行。

接下来,前一个查询用于使用变量@rank来计算排名:

SELECT player_id, total_sum, @rank:=@rank+1 AS rank 
FROM (
...) AS sq, 
(SELECT @rank:=0) AS tr

由以下内容初始化:

SELECT @rank:=0

最后,通过这些数据,您可以选择要知道的内容,例如player_id=1的排名,如第一个查询中所示。

答案 1 :(得分:0)

@agold 提供的解决方案是正确的。

这是另一个很好的解决方案:

SELECT 
    player_id, 
    total_sum, 
    RANK() OVER(ORDER BY total_sum DESC) as rank
FROM (
    SELECT 
        player_id, 
        SUM(total_points) AS total_sum
    FROM players
    WHERE season_id=1 -- optional filter
    GROUP BY player_id
    ORDER BY total_sum DESC
) AS sq;