How to find pairs of events with postgres?

跟風遠走 提交于 2019-12-11 15:46:51

问题


I have an events 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

And I want to find the pairs of events:

  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  |

What sort of query could do this?


回答1:


You can do this pretty easily with a window function. Among other things, these let you reference the next/previous row in a query result (via lead() and lag()). For example:

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'



回答2:


Just got this working. Is there a more efficient way?

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
;


来源:https://stackoverflow.com/questions/50641682/how-to-find-pairs-of-events-with-postgres

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!