如何使用窗口滞后功能对具有多种传感器类型的数据进行分区

时间:2018-07-04 13:29:30

标签: sql postgresql time-series

我正在尝试使用postgres LAG函数来计算系统中每个传感器的两个采样日期之间的绝对时间差。

我能想到的最好的方法是使用WINDOW LAG函数来计算与前一行的差。但是,这有两个问题。第一个值始终为null。我猜我可以使用CASE函数解决此问题。其次,它不会显式获取每个传感器的值。

SELECT 
    seq_id, stream_id, sensor, "timestamp", oper_value 
    "timestamp" - LAG("timestamp",1) OVER (ORDER BY "timestamp") delta
    FROM public.mt_events
    where "type" = 'operational_value_event'
    limit 100;

当违反阈值(包括滞后)时记录数据,因此某些值的更改频率高于其他值。记录数据的时间间隔没有固定。

获得具有至少一定时间差的值的最终目标。

示例数据:

id stream_id sensor oper_value timestamp
44 100000000    GT1         17 2018-05-16 13:36:21.899821+00
45 100000000    GT2         44 2018-05-16 14:36:21.000000+00
88 100000000    GT1         26 2018-05-18 12:33:22.000000+00
94 100000000    GT1         99 2018-05-18 12:33:23.002000+00

例如,如果选择时差至少为5分钟的数据,我希望获得以下值:

id stream_id sensor oper_value timestamp
44 100000000    GT1         17 2018-05-16 13:36:21.899821+00
45 100000000    GT2         44 2018-05-16 14:36:21.000000+00
88 100000000    GT1         26 2018-05-18 12:33:22.000000+00

由于差异少于5分钟,因此最后一个GT1被过滤掉了。

是否有任何方法可以使用SQL语句来执行此操作,还是需要编写存储过程?

干杯,  马里奥

1 个答案:

答案 0 :(得分:1)

您可以将lag()的三个参数形式与partition by一起使用:

("timestamp" -
 LAG("timestamp", 1, "timestamp") OVER (PARTITION BY sensor ORDER BY "timestamp")
) as delta

对于您的最终问题,第一行的NULL值无关紧要。您可以使用子查询解决问题:

select *
from (select seq_id, stream_id, sensor, "timestamp", oper_value ,
             lag("timestamp") over (partition by sensor order by timestamp) as prev_timestamp
      from public.mt_events
      where "type" = 'operational_value_event'
     ) t
where delta is null or
      prev_timestamp < timestamp - interval '5 minute';