计算年份之间平均每月的差异

时间:2020-06-07 10:43:15

标签: sql postgresql date window-functions

我有一张表格,其中包含过去3年中传感器的平均每月数值

有没有一种方法可以计算出例如2019年的月度值和2018年的月度值之间的差异,并可能创建一个新表或视图,其中将2018年的日期包含在一列中,即2019年的日期另一个是传感器读数值的差异?

example table

谢谢

TP

2 个答案:

答案 0 :(得分:0)

假设您的数据没有丢失的月份/年份,则可以使用一种窗口功能:

select 
    t.*,
    lag(average) over(
        partition by sensor_id, extract(month from m)
        order by extract(year from m)
    ) last_year_average
from mytable

这会将属于同一传感器和同一月份的所有行放在同一分区中。然后,您可以将时间戳的年份部分用作排序列。

您可以根据需要使用新列将其与当前平均值进行比较。

答案 1 :(得分:0)

如果您每个月都有一个值,则可以使用12个月的滞后时间:

select t.*,
       lag(average, 12) over (partition by sensor_id
                              order by m
                             ) as last_year_average
from t;

将其过滤到仅2019/2018年需要一个子查询:

select t.*
from (select t.*,
             lag(average, 12) over (partition by sensor_id
                                    order by m
                                   ) as last_year_average
      from t
     ) t
where m >= '2019-01-01'::date and
      m < '2020-01-01'::date

如果您缺少几个月,那么这两个问题(以及GMB的答案)都将无法正常工作。而是可以使用join,聚合或窗口函数:

select t.*
from t left join
     t tprev
     on tprev.sensor_id = t.sensor_id and
        tprev.m = t.m - interval '12 month'
where t.m >= '2019-01-01'::date and t.m < '2020-01-01'::date;

其他两种方法是:

select t.sensor_id, month(t.m)
       max(average) filter (where year(t.m) = 2019) as avg_2019,
       max(average) filter (where year(t.m) = 2018) as avg_2018
from t
group by t.sensor_id, month(t.m);

如果可能会丢失月份,请安全使用窗口功能:

select t.*,
       max(average) over (partition by sensor_id
                          order by m
                          range between '1 year preceding' and '1 year preceding'
                         ) as average_prev
from t;