获得池中每个人每月的前 3 名
Posted
技术标签:
【中文标题】获得池中每个人每月的前 3 名【英文标题】:Get Top 3 Scores for Each Month For Each Person in a Pool 【发布时间】:2021-02-17 14:22:29 【问题描述】:我有一个 PostgreSQL 数据库,用于跟踪魔术池中的人的得分。池中的每个玩家都可以在给定的月份内玩多场比赛,有时在给定的一天也可以玩多场比赛。
例如玩家 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)。
当我只有一个月的时间时,我可以毫无问题地获得当月的前 3 名;但是现在我有好几个月的时间,我无法让我的代码工作。我已经修改了我的原始代码,这就是我想出的
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、基于月份的分区、子查询;但似乎没有什么能给我我想要的东西。我得到的最干净的结果是上面的代码。我正在寻找关于如何获得我需要的东西的一些指导。提前致谢。
【问题讨论】:
【参考方案1】:如果您想要每个玩家和每个月的前三名,请使用窗口函数:
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
子句(最好直接放在子查询中)。
【讨论】:
谢谢。我一直在寻找按玩家和月份汇总结果。我的一次尝试中有类似的东西。但从未使用 row_number() 来获得我想要的东西。 完成。不过我确实有一个问题,因为我不确定我是否理解“d(game_month)”在做什么。是为“game_month”创建别名“d”还是创建别名“d”和别名“game_month”?我以前从未见过这样写的别名。以上是关于获得池中每个人每月的前 3 名的主要内容,如果未能解决你的问题,请参考以下文章