获得池中每个人每个月的前 3 名分数

Get Top 3 Scores for Each Month For Each Person in a Pool

我有一个 PostgreSQL 数据库,用于跟踪 Magic pool 中的人员得分。池中的每个玩家可以在给定的月份玩多场比赛,有时在给定的一天玩多场比赛。

例如玩家 1,根据每个月玩的所有游戏,10 月打了 5 场比赛共计 11 分,11 月打了 6 场比赛共计 62 分

Game#   Game Date     Points Earned
1      02-Oct-2020      3
2      02-Oct-2020      2
3      09-Oct-2020      3
4      10-Oct-2020      1
5      24-Oct-2020      2
6      02-Nov-2020      4
7      06-Nov-2020      32
8      06-Nov-2020     -4
9      07-Nov-2020      33
10     07-Nov-2020      1
11     10-Nov-2020     -4

我想要做的是为玩家获得每个月的前 3 名分数。 10 月总计 8 分 (3+2+3),11 月总计 69 分 (32+33+4)。

当我只有一个月的时候,我可以毫无问题地获得当月的前三名;但是现在我有好几个月了,我无法让我的代码工作。我已经修改了我的原始代码,这就是我想出的

SELECT
  player_name, 
  EXTRACT(MONTH FROM game_date) AS game_month,
  sum(player_pts) AS monthly_pts
FROM testdb.player_points
WHERE player_name = 'player1'
    GROUP BY player_name, game_month
    ORDER BY game_month
    LIMIT 3;

上面的代码返回给我的是每个月的总积分。 10 月为 11,11 月为 62,根据我的代码,这是我所期望的;但不是我想要的。我尝试使用 INNER JOINS,基于月份的分区,子查询;但似乎没有什么能给我我正在寻找的东西。我得到的最干净的结果是上面的代码。我正在寻找有关如何获得所需内容的一些指导。提前致谢。

如果您想要每个玩家和每个月的前三名,请使用 window 函数:

select *
from (
    select pp.*, 
        row_number() over(partition player_name, date_trunc('month', game_date) order by player_pts desc) rn
    from testdb.player_points pp
) pp
where rn <= 3

然后您可以按玩家和月份汇总结果,如果您需要的话:

select player_name, game_month, sum(player_points) top_3_points
from (
    select pp.*, d.*
        row_number() over(partition pp.player_name, d.game_month order by pp.player_pts desc) rn
    from testdb.player_points pp
    cross join lateral (values (date_trunc('month', game_date))) d(game_month)
) pp
where rn <= 3
group by player_name, game_month

我将日期截断移动到横向连接,这样我就不必输入两次了。如果你想要特定玩家的结果,那么你可以使用 where 子句(最好直接放在子查询中)。