PostgreSQL 计算组和顺序的滚动平均值

PostgreSQL calculate rolling average with group and order

我有一个table如下

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) 平均值不应包括当前行

提前致谢

我们可以使用带有 window 框架的 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;

Demo

COALESCE() 的调用是必要的,因为您似乎期望如果前三行都是 NULL (这发生在每个 id 组中的第一条记录) ,则应使用当前行的 value