【问题标题】:psql: how to group similar consecutive events on a table with timestamppsql:如何在带有时间戳的表上对类似的连续事件进行分组
【发布时间】:2021-04-28 04:37:40
【问题描述】:

我在事件表上遇到问题。

我在一个两列表上输入和退出事件,我需要获取 in_time 的间隔。 问题是传感器设备(相机上的神经元网络仍在开发中)不是那么精确,有时我会收到不止一个进入事件,然后只有一个退出事件,所以表格最终如下所示。

ts event device
2021-04-28 00:00:00 enter 1
2021-04-28 00:01:00 exit 1
2021-04-28 00:02:00 enter 1
2021-04-28 00:04:00 enter 1
2021-04-28 00:06:00 enter 2
2021-04-28 00:08:00 exit 1
2021-04-28 00:10:00 enter 2
2021-04-28 00:11:00 enter 2
2021-04-28 00:14:00 exit 2

我要满足的条件是间隔 = 退出 - 首先进入批次的事件。 我的想法是得到下表,然后使用lag (ts,-1) 得到减法。

ts event device
2021-04-28 00:00:00 enter 1
2021-04-28 00:01:00 exit 1
2021-04-28 00:02:00 enter 1
2021-04-28 00:08:00 exit 1
2021-04-28 00:06:00 enter 2
2021-04-28 00:14:00 exit 2

知道如何获得这张桌子吗? 谢谢!

PS: 真实表使用 uuid 作为键,而不是数值。

PS2: 我想要的最终结果就是这个

occupancy device
00:01:00 1
00:06:00 1
00:08:00 2

我想我可以从第二个获得它,但如果有另一条我看不到的路径可以从第一个获得这张表而不经过第二个,那么知道会很有趣,

再次感谢您!

【问题讨论】:

    标签: sql postgresql datetime


    【解决方案1】:

    第 1 步: 使用窗口函数lag 检查给定传感器的先前事件(由ts 排序)是否与当前行中的事件不同,并仅保留具有不同事件的行。

    with sensor_events (ts, event_name, device) as ( 
    values
      (timestamp '2021-04-28 00:00:00'  ,'enter',   1),
      (timestamp '2021-04-28 00:01:00'  ,'exit',    1),
      (timestamp '2021-04-28 00:02:00'  ,'enter',   1),
      (timestamp '2021-04-28 00:04:00'  ,'enter',   1),
      (timestamp '2021-04-28 00:06:00'  ,'enter',   2),
      (timestamp '2021-04-28 00:08:00'  ,'exit',    1),
      (timestamp '2021-04-28 00:10:00'  ,'enter',   2),
      (timestamp '2021-04-28 00:11:00'  ,'enter',   2),
      (timestamp '2021-04-28 00:14:00'  ,'exit',    2)
    )
    , distinct_events AS (
    select *
      , lag(event_name) over 
        (partition by device order by ts) 
        is distinct from event_name 
        AS is_distinct_event
    from sensor_events
    )
    select ts, event_name, device
    from distinct_events
    where is_distinct_event
    

    输出:

    ts                          event_name  device
    2021-04-28T00:00:00.000Z    enter            1
    2021-04-28T00:01:00.000Z    exit             1
    2021-04-28T00:02:00.000Z    enter            1
    2021-04-28T00:08:00.000Z    exit             1
    2021-04-28T00:06:00.000Z    enter            2
    2021-04-28T00:14:00.000Z    exit             2
    

    第 2 步:再次使用 lag 函数计算退出和进入事件之间的时间差。

    with sensor_events (ts, event_name, device) as ( 
    values
      (timestamp '2021-04-28 00:00:00'  ,'enter',   1),
      (timestamp '2021-04-28 00:01:00'  ,'exit',    1),
      (timestamp '2021-04-28 00:02:00'  ,'enter',   1),
      (timestamp '2021-04-28 00:04:00'  ,'enter',   1),
      (timestamp '2021-04-28 00:06:00'  ,'enter',   2),
      (timestamp '2021-04-28 00:08:00'  ,'exit',    1),
      (timestamp '2021-04-28 00:10:00'  ,'enter',   2),
      (timestamp '2021-04-28 00:11:00'  ,'enter',   2),
      (timestamp '2021-04-28 00:14:00'  ,'exit',    2)
    )
    , distinct_events AS (
    select *
      , lag(event_name) over 
        (partition by device order by ts) 
        is distinct from event_name 
        AS is_distinct_event
    from sensor_events
    )
    , occupancy AS (
      select 
        ts - lag(ts) over w occupancy
      , event_name
      , lag(event_name) over w last_event_name
      , device
      from distinct_events
      where is_distinct_event
      window w as (partition by device order by ts)
    )
    select 
    occupancy, device
    from occupancy
    where event_name = 'exit' 
      and last_event_name = 'enter'
    

    这将输出你所追求的表格。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-15
      相关资源
      最近更新 更多