【发布时间】:2020-09-26 08:38:52
【问题描述】:
我有一张表格,其中包含传感器在过去 3 年中的平均每月值
有没有一种方法可以计算例如 2019 年的月度值和 2018 年的月度值之间的差异,或者创建一个新表或视图,其中包含 2018 年的日期在一列中,2019 年的日期在另一个和第三个传感器读数值的差异?
谢谢
TP
【问题讨论】:
标签: sql postgresql date window-functions
我有一张表格,其中包含传感器在过去 3 年中的平均每月值
有没有一种方法可以计算例如 2019 年的月度值和 2018 年的月度值之间的差异,或者创建一个新表或视图,其中包含 2018 年的日期在一列中,2019 年的日期在另一个和第三个传感器读数值的差异?
谢谢
TP
【问题讨论】:
标签: sql postgresql date window-functions
假设您的数据没有丢失月份/年份,一个选项使用窗口函数:
select
t.*,
lag(average) over(
partition by sensor_id, extract(month from m)
order by extract(year from m)
) last_year_average
from mytable
这会将属于同一传感器和同一月份的所有行放在同一分区中。然后,您可以将时间戳的年份部分用作排序列。
您可以根据需要使用新列将其与当前平均值进行比较。
【讨论】:
如果你每个月都有一个值,你可以使用 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;
【讨论】: