This is a type of gaps-and-islands problem. Because you want any overlaps, I would go for a cumulative max of the previous enddate
to determine where the islands being:
select id, name, min(startdate) as startdate,
(case when count(enddate) = count(*) then max(enddate)
end) as enddate
from (select t.*,
sum(case when prev_enddate >= startdate then 0 else 1 end) over (partition by id, name) as grp
from (select t.*,
max(enddate) over (partition by id, name order by startdate range between unbounded preceding and interval '1' day preceding) as prev_enddate
from t
) t
) t
group by id, name, grp
order by name, startdate;
Here is a db<>fiddle.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…