Reputation: 43
I have the following PostgreSQL table "event"
CREATE TABLE event (
user INTEGER,
name VARCHAR(255),
begin_timestamp TIMESTAMP,
end_timestamp TIMESTAMP
);
Data in the table:
╔══════╦══════╦═════════════════════╦═════════════════════╗
║ user ║ name ║ begin_timestamp ║ end_timestamp ║
╠══════╬══════╬═════════════════════╬═════════════════════╣
║ 5 ║ foo ║ 2020-07-23 16:11:00 ║ 2020-07-23 16:28:00 ║
║ 5 ║ bar ║ 2020-07-23 16:40:00 ║ 2020-07-23 16:40:00 ║
║ 5 ║ abcd ║ 2020-07-23 00:00:00 ║ 2020-07-23 00:37:00 ║
║ 7 ║ foo ║ 2020-07-23 18:12:00 ║ 2020-07-23 18:23:00 ║
║ 7 ║ bar ║ 2020-07-23 11:00:00 ║ 2020-07-23 11:00:00 ║
║ 8 ║ foo ║ 2020-07-23 00:00:00 ║ 2020-07-23 03:00:00 ║
║ ... ║ ... ║ ... ║ ... ║
╚══════╩══════╩═════════════════════╩═════════════════════╝
How can I get the time between two events for a specific user? (NOT the duration of a specific event)
Example: The time between the event "foo" and the event "bar" for the user "5" was 12 minutes, because the event "foo" ended at 2020-07-23 16:28:00 and the event "bar" began at 2020-07-23 16:40:00.
So far I have these queries:
SELECT end_timestamp FROM event WHERE name = 'foo' and user = 5
SELECT begin_timestamp FROM event WHERE name = 'bar' and user = 5
SELECT (end_timestamp - begin_timestamp) AS duration FROM event WHERE name = 'foo' AND user = 5;
Upvotes: 1
Views: 37
Reputation: 1269445
You can use lag()
. Assuming at most one "foo" and "bar" per event:
select e.*,
(begin_timestamp - prev_end_timestamp) as duration
from (select e.*, lag(end_timestamp) over (partition by name order by begin_timestamp) as prev_end_timestamp
from event e
where e.name in ('foo', 'bar')
) e
where e.name = 'bar';
You can also phrase this using aggregation:
select user,
( max(begin_timestamp) filter (where name = 'bar') -
min(end_timestamp) filter (where name = 'foo')
) as duration
from event e
where e.name in ('foo', 'bar')
group by user
Upvotes: 1