Prepare sample data:
create table tab (id int, study_start_time int, study_end_time int);
insert into tab
select * from (
select 1234 as id, 168 as study_start_time, 256 as study_end_time union all
select 2345, 175, 233 union all
select 1234, 256, 300 union all
select 1234, 300, 389 union all
select 1234, 389, 439 union all
select 1234, 439, 460 union all
select 1234, 460, 480 union all
select 2345, 400, 425 union all
select 4567, 200, 225 union all
select 4567, 250, 270 union all
select 4567, 270, 289 union all
select 4567, 300, 310 union all
select 4567, 320, 340 union all
select 4567, 360, 370 union all
select 4567, 370, 390
) t;
The way to "merge" rows:
Maybe I've overcomplicated it but the result is as expected :-). There is a chance to simplify it in SQL Server 2005+ using CTE and still get "oneliner" or use a temporary table (most RDBMS) and do it in more than one line.
select * from (
select m1.id, m1.study_start_time, m2.study_end_time
from (
select t.id, t.study_start_time, t.study_end_time,
t2.study_end_time as et, t3.study_start_time as st
from tab t
left join tab t2 on t2.id = t.id and t2.study_start_time = t.study_end_time
left join tab t3 on t3.id = t.id and t3.study_end_time = t.study_start_time
) m1
join (
select m1.*
from (
select t.id, t.study_start_time, t.study_end_time,
t2.study_end_time as et, t3.study_start_time as st
from tab t
left join tab t2 on t2.id = t.id and t2.study_start_time = t.study_end_time
left join tab t3 on t3.id = t.id and t3.study_end_time = t.study_start_time
) m1
where m1.et is null and m1.st is not null
) m2 on m1.id = m2.id and m2.study_end_time = (
select min(study_end_time)
from (
select t.id, t.study_start_time, t.study_end_time,
t2.study_end_time as et, t3.study_start_time as st
from tab t
left join tab t2 on t2.id = t.id and t2.study_start_time = t.study_end_time
left join tab t3 on t3.id = t.id and t3.study_end_time = t.study_start_time
) m3
where m3.id = m1.id and m3.study_end_time >= m1.study_end_time and m3.et is null and m3.st is not null
)
where m1.et is not null and m1.st is null
union
select id, study_start_time, study_end_time
from (
select t.id, t.study_start_time, t.study_end_time,
t2.study_end_time as et, t3.study_start_time as st
from tab t
left join tab t2 on t2.id = t.id and t2.study_start_time = t.study_end_time
left join tab t3 on t3.id = t.id and t3.study_end_time = t.study_start_time
) m3 where m3.et is null and m3.st is null
) tab
order by id, study_start_time;
Final result:
id study_start_time study_end_time
----------- ---------------- --------------
1234 168 480
2345 175 233
2345 400 425
4567 200 225
4567 250 289
4567 300 310
4567 320 340
4567 360 390