Я интерпретирую это как тип проблемы пробелов и островков. Каждый «остров» начинается с задержки в 5 минут для «Read» или любой строки с «Delivered».
with tgrp as (
select t.*,
sum(case when modules = 'Delivered' or
prev_timestamp < timestamp - interval '5' minute
then 1 else 0
end) over (partition by id order by timestamp) as grp
from (select t.*,
lag(timestamp) over (partition by id order by timestamp) as prev_timestamp
from t
) t
)
select id,
max(case when seqnum = 1 then module end) as module1,
max(case when seqnum = 1 then timestamp end) as timestamp1,
max(case when seqnum = 2 then module end) as module2,
max(case when seqnum = 2 then timestamp end) as timestamp2
from (select tgrp.*,
row_number() over (partition by id, grp order by timestamp) as seqnum
from tgrp
) tgrp
group by id, grp;
EDIT:
Я думаю, что более простой способ - это поставить данные вместе, используя lead()
, а затем фильтруйте и корректируйте окончательные значения:
select t.id, t.module, t.timestamp,
(case when t.next_module = 'Read' and
t.next_timestamp < t.timestamp + interval '5' minute
then t.next_module
end) as module2,
(case when t.next_module = 'Read' and
t.next_timestamp < t.timestamp + interval '5' minute
then t.next_timestamp
end) as timestamp2
from (select t.*,
lead(module) over (partition by id order by timestamp) as next_module,
lead(timestamp) over (partition by id order by timestamp) as next_timestamp
from t
) t
where module = 'Delivery' or
(next_timestamp > timestamp + interval '5' minute)