Вам необходимо определить, где начинаются диапазоны. В вашем случае они, кажется, имеют точное совпадение конца и начала, поэтому вы можете использовать lag()
, чтобы определить, где начинаются группы. Совокупное количество пусков обеспечивает идентификатор группировки, который можно использовать для агрегирования:
select id, min(start) as start, max(end) as end
from (select t.*, countif(prev_end is null or prev_end <> start) over (partition by id order by start) as grp
from (select t.*, lag(end) over (partition by id order by start) as prev_end
from t
) t
) t
group by id, grp;
Если группы могут перекрываться, то кумулятивный максимум обычно делает свое дело:
select id, min(start) as start, max(end) as end
from (select t.*, countif(prev_end is null or prev_end <> start) over (partition by id order by start) as grp
from (select t.*,
max(end) over (partition by id order by start rows between unbounded preceding and 1 preceding) as prev_end
from t
) t
) t
group by id, grp;