Đây là một phương pháp để giải quyết vấn đề này. Tạo cờ xác định xem một bản ghi có không trùng lặp với cái trước. Đây là sự khởi đầu của một nhóm. Sau đó, lấy tổng tích lũy của cờ này và sử dụng cờ đó để nhóm:
select user_id, min(begin_at) as begin_at, max(end_at) as end_at
from (select s.*, sum(startflag) over (partition by user_id order by begin_at) as grp
from (select s.*,
(case when lag(end_at) over (partition by user_id order by begin_at) >= begin_at
then 0 else 1
end) as startflag
from slots s
) s
) s
group by user_id, grp;
Tại đây là một SQL Fiddle.