【问题标题】:Calculating differences in average monthly between years计算年平均月度差异
【发布时间】:2020-09-26 08:38:52
【问题描述】:

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

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

谢谢

TP

【问题讨论】:

    标签: sql postgresql date window-functions


    【解决方案1】:

    假设您的数据没有丢失月份/年份,一个选项使用窗口函数:

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

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

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

    【讨论】:

    • 谢谢你..结合下面的选项,你们都帮了我很多
    【解决方案2】:

    如果你每个月都有一个值,你可以使用 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;
    

    【讨论】:

    • 感谢所有选项。我是一个初学者,所以有很多工作要做。您的第二个选项似乎正是我所追求的,但我也在努力通过其他选项
    猜你喜欢
    • 1970-01-01
    • 2018-04-24
    • 1970-01-01
    • 1970-01-01
    • 2021-03-28
    • 2016-10-04
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    相关资源
    最近更新 更多