获得池中每个人每个月的前 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
子句(最好直接放在子查询中)。
我有一个 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
子句(最好直接放在子查询中)。