Dengan asumsi kita bisa menggunakan start_date
untuk mengidentifikasi catatan yang berdekatan (yaitu, tidak ada celah), maka Anda dapat menggunakan pendekatan selisih nomor baris:
select id, min(start_date) as mn_date, max(end_date) as mx_date, rate
from (select t.*,
row_number() over (partition by id order by start_date) as seqnum_i,
row_number() over (partition by id, rate order by start_date) as seqnum_ir
from t
) t
group by id (seqnum_i - seqnum_ir), rate;
Untuk melihat cara kerjanya, lihat hasil subquery. Anda seharusnya dapat "melihat" bagaimana perbedaan dari dua nomor baris menentukan grup record yang berdekatan dengan rate yang sama.