Vis*_*han 4 sql postgresql rolling-computation
我有一张表如下
id | x | y | value
------+--------+-------+------------
1 | 1 | 1 | 25
1 | 1 | 2 | 42
1 | 2 | 3 | 98
1 | 2 | 4 | 54
1 | 3 | 5 | 67
2 | 1 | 1 | 78
2 | 1 | 2 | 45
2 | 2 | 3 | 96
Run Code Online (Sandbox Code Playgroud)
我必须按 id 对其进行分组,同时按 id、x 和 y(按各自的顺序)保持顺序,并计算前 n 行的滚动平均值。例如,如果 n = 3
id | x | y | value | rollingAvg
------+--------+-------+--------+-----------
1 | 1 | 1 | 25 | 25
1 | 1 | 2 | 42 | (25 / 1) = 25
1 | 2 | 3 | 98 | (25+42/2) = 33.5
1 | 2 | 4 | 54 | (25+42+98 /3) = 55
1 | 3 | 5 | 67 | (42+98+54 /3) = 64.67
2 | 1 | 1 | 78 | 78
2 | 1 | 2 | 45 | (78/1) = 78
2 | 2 | 3 | 96 | (78+45 / 2) = 61.5
Run Code Online (Sandbox Code Playgroud)
逻辑是
1)如果按id分组时该行是第一行,则该值应该是平均值
2)平均值不应包括当前行
提前致谢
Tim*_*sen 10
我们可以使用AVG()带有窗框的函数来仅覆盖前三行:
select
id,
x,
y,
coalesce(avg(value) over
(partition by id order by y rows between 3 preceding AND 1 preceding), value) as rollingAvg
from your_table
order by id, y;
Run Code Online (Sandbox Code Playgroud)
调用COALESCE()是必要的,因为您似乎期望如果前三行都是全部NULL(每组中的第一条记录都会发生这种情况),那么应该使用id当前行。value