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

时间:2019-05-01 07:25:16

标签: 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

我必须按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分组,该行是第一行,则该值应为平均值

2)平均值不应包含当前行

预先感谢

1 个答案:

答案 0 :(得分:3)

我们可以将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;

enter image description here

Demo

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