多个窗口函数的累积和 [英] Cumulative sum of multiple window functions
问题描述
我有一个结构如下的表:
I have a table with the structure:
id | date | player_id | score
--------------------------------------
1 | 2019-01-01 | 1 | 1
2 | 2019-01-02 | 1 | 1
3 | 2019-01-03 | 1 | 0
4 | 2019-01-04 | 1 | 0
5 | 2019-01-05 | 1 | 1
6 | 2019-01-06 | 1 | 1
7 | 2019-01-07 | 1 | 0
8 | 2019-01-08 | 1 | 1
9 | 2019-01-09 | 1 | 0
10 | 2019-01-10 | 1 | 0
11 | 2019-01-11 | 1 | 1
我想再创建两列, total_score, last_seven_days。
I want to create two more columns, 'total_score', 'last_seven_days'.
total_score是player_id得分的滚动总和
total_score is a rolling sum of the player_id score
last_seven_days是最近7天(包括之前和之后)的得分日期
last_seven_days is the score for the last seven days including to and prior to the date
我编写了以下SQL查询:
I have written the following SQL query:
SELECT id,
date,
player_id,
score,
sum(score) OVER all_scores AS all_score,
sum(score) OVER last_seven AS last_seven_score
FROM scores
WINDOW all_scores AS (PARTITION BY player_id ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING),
last_seven AS (PARTITION BY player_id ORDER BY id ROWS BETWEEN 7 PRECEDING AND 1 PRECEDING);
并获得以下输出:
id | date | player_id | score | all_score | last_seven_score
------------------------------------------------------------------
1 | 2019-01-01 | 1 | 1 | |
2 | 2019-01-02 | 1 | 1 | 1 | 1
3 | 2019-01-03 | 1 | 0 | 2 | 2
4 | 2019-01-04 | 1 | 0 | 2 | 2
5 | 2019-01-05 | 1 | 1 | 2 | 2
6 | 2019-01-06 | 1 | 1 | 3 | 3
7 | 2019-01-07 | 1 | 0 | 4 | 4
8 | 2019-01-08 | 1 | 1 | 4 | 4
9 | 2019-01-09 | 1 | 0 | 5 | 4
10 | 2019-01-10 | 1 | 0 | 5 | 3
11 | 2019-01-11 | 1 | 1 | 5 | 3
我意识到我需要更改此
last_seven AS(按玩家ID顺序排列ID排在7个开头和1个开头之间)
而不是7,而是使用某种日期格式,因为仅使用数字7会引入错误。
to instead of being 7, to use some sort of date format because just having the number 7 will introduce errors.
ie能够执行日期-2天
或日期-6天
我还想添加3个月,6个月,12个月之后的列,因此需要它能够保持动态。
I also would like to add columns such as 3 months, 6 months, 12 months later down the track and so need it to be able to be dynamic.
推荐答案
Postgres 11 + 的解决方案:
像@LaurenzAlbe一样使用 RANGE区间
Using RANGE interval
as @LaurenzAlbe did
Postgres< 11 的解决方案:
(仅显示天部分,即 all_scores 部分是相同的)
(just presenting the "days" part, the "all_scores" part is the same)
在 player_id
和$ vant date
范围:
Joining the table against itself on the player_id
and the relevant date
range:
SELECT s1.*,
(SELECT SUM(s2.score)
FROM scores s2
WHERE s2.player_id = s1.player_id
AND s2."date" BETWEEN s1."date" - interval '7 days' AND s1."date" - interval '1 days')
FROM scores s1
这篇关于多个窗口函数的累积和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!