Это можно сделать с помощью следующей логики.
Вы можете получить все in
с помощью запроса lead()
.Затем вы можете получить непревзойденные значения out
s, используя lag()
:
select t.eid, date as timein,
(case when next_type = 'OUT' then next_date end) as timeout,
((case when next_type = 'OUT' then next_date end) - date) * (24 * 60) as diff_in_minutes
from (select t.*,
lead(type) over (partition by eid order by date) as next_type,
lead(type) over (partition by eid order by date) as next_date
from t
) t
where type = 'IN'
union all
select t.eid, null as timein,
date as timeout, null as diff_in_minutes
from (select t.*,
lag(type) over (partition by eid order by date) as prev_type,
lag(date) over (partition by eid order by date) as prev_date
from t
) t
where type = 'OUT' and (prev_type <> 'IN' or prev_type is null);
Здесь - это скрипта db <> со всеми вашими данными, показывающая, что она поддерживает несколько входови OUTs.
Обратите внимание, что предполагается, что столбец даты / времени действительно равен date
.Он преобразуется только в timestamp
для отображения компонента времени в наборе результатов.