Я думаю, что это проблема разрыва и островов. В этом случае вы можете использовать разницу номера строки:
select id, email, min(eff_dt), max(exp_dt)
from (select t.*,
row_number() over (partition by id order by eff_dt) as seqnum,
row_number() over (partition by id, email order by eff_dt) as seqnum_e
from t
) t
group by email, (seqnum - seqnum_e);