问题
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