I am trying to combine overlapping start timestamps at once. A similar issue is available here on SO. I would like to combine timestamps separately for each user with data.
SQLFiddle
Sample data:
create table app_log (
user_id int,
login_time timestamp,
logout_time timestamp
);
insert into app_log values
(1, '2014-01-01 08:00', '2014-01-01 10:00'),
(1, '2014-01-01 09:10', '2014-01-01 09:59'),
(1, '2014-01-01 10:00', '2014-01-01 10:48'),
(1, '2014-01-01 10:40', '2014-01-01 10:49'),
(1, '2014-01-01 10:55', '2014-01-01 11:00'),
(2, '2014-01-01 09:00', '2014-01-01 11:00'),
(2, '2014-01-01 10:10', '2014-01-01 10:59'),
(2, '2014-01-01 11:00', '2014-01-01 11:48'),
(2, '2014-01-01 11:40', '2014-01-01 11:49'),
(2, '2014-01-01 11:55', '2014-01-01 12:00')
;
Required Results:
used_id login_time logout_time
1 2014-01-01 08:00 2014-01-01 10:49
1 2014-01-01 10:55 2014-01-01 11:00
2 2014-01-01 09:00 2014-01-01 11:49
2 2014-01-01 11:55 2014-01-01 12:00
I tried to use the solutions indicated in the mentioned question , but it does not return the correct answer even for one user:
with recursive
in_data as (select login_time as d1, logout_time as d2 from app_log where user_id = 1)
, dateRanges (ancestorD1, parentD1, d2, iter) as
(
select
d1 as ancestorD1,
d1 as parentD1,
d2,
cast(0 as int) as iter
from in_data
union all
select
tLeft.ancestorD1,
tRight.d1 as parentD1,
tRight.d2,
iter + 1 as iter
from dateRanges as tLeft join in_data as tRight
on tLeft.d2 between tRight.d1 and tRight.d2
and not (tLeft.parentD1 = tRight.d1 and tLeft.d2 = tRight.d2)
)
select
ranges1.*
from dateRanges as ranges1
where not exists (
select 1
from dateRanges as ranges2
where ranges1.ancestorD1 between ranges2.ancestorD1 and ranges2.d2
and ranges1.d2 between ranges2.ancestorD1 and ranges2.d2
and ranges2.iter > ranges1.iter
);
Results in:
ancestord1 parentd1 d2 iter
2014-01-01 10:55:00;2014-01-01 10:55:00;2014-01-01 11:00:00;0
2014-01-01 08:00:00;2014-01-01 10:40:00;2014-01-01 10:49:00;2
2014-01-01 09:10:00;2014-01-01 10:40:00;2014-01-01 10:49:00;3
What is wrong with the request above and how can I expand it to get results from users? Is there a better solution to this problem in PostgreSQL?