如何使用 postgres 查找事件对?

How to find pairs of events with postgres?

我有一个活动 table:

             ts             |  user  | reason 
----------------------------+--------+--------
 2018-06-01 10:44:15.52+01  | 359999 | START
 2018-06-01 10:44:29.521+01 | 359999 | STOP
 2018-06-01 10:44:43.52+01  | 359998 | START
 2018-06-01 10:44:55.52+01  | 359999 | START
 2018-06-01 10:44:59.521+01 | 359998 | STOP
 2018-06-01 10:45:07.52+01  | 359999 | STOP
 2018-06-01 10:46:16.52+01  | 359999 | START

我想找到事件对:

  user  |           start            |            stop            
--------+----------------------------+----------------------------
 359999 | 2018-06-01 10:44:15.52+01  | 2018-06-01 10:44:29.521+01
 359998 | 2018-06-01 10:44:43.52+01  | 2018-06-01 10:44:59.521+01
 359999 | 2018-06-01 10:44:55.52+01  | 2018-06-01 10:45:07.52+01
 359999 | 2018-06-01 10:46:16.52+01  |

什么样的查询可以做到这一点?

刚刚开始工作。有没有更有效的方法?

select imei, reason, ts AS start, (
    select ts
    from events as stops
    where stops.ts > starts.ts
    and reason = 'STOP'
    and stops.user = starts.user
    order by ts desc
    limit 1
) as stop
from events as starts
where reason = 'START'
order by ts
;

您可以使用 window function 轻松完成此操作。除其他外,这些可以让您在查询结果中引用 next/previous 行(通过 lead()lag())。例如:

SELECT "user", ts AS start, next_ts AS stop
FROM (
  SELECT *, lead(ts) OVER (PARTITION BY "user" ORDER BY ts) AS next_ts
  FROM events
  WHERE reason IN ('START', 'STOP')
) AS ts_pairs
WHERE reason = 'START'