我有一张桌子如下
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
我必须通过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
逻辑是
1)如果按ID分组时行是第1行,则该值应为平均值
2)平均值不应包括当前行
提前致谢
我们可以使用带有窗口框架的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;
对COALESCE()
的调用是必要的,因为你似乎期望如果前三行都是NULL
(这发生在每个id
组的第一条记录中),那么应当使用当前行的value
。