Pode haver uma maneira de fazer isso em um SQL select, mas me escapa. Eu consegui fazer isso com uma função armazenada embora. Aqui está o que eu fiz para o meu teste:
create table work
(id integer, start_date date, end_date date);
insert into work values (1, '2011-01-01','2011-02-02');
insert into work values (1, '2011-02-02','2011-04-04');
insert into work values (1, '2011-06-06','2011-09-09');
insert into work values (2, '2011-01-01','2011-02-02');
insert into work values (2, '2011-02-02','2011-03-03');
create or replace function get_data() returns setof work as
$body$
declare
res work%rowtype;
sd date := null;
begin
for res in
select
w1.id,
case when exists (select 1 from work w2 where w1.id=w2.id and w2.end_date=w1.start_date) then null else w1.start_date end,
case when exists (select 1 from work w2 where w1.id=w2.id and w2.start_date=w1.end_date) then null else w1.end_date end
from
work w1
order by
id, start_date, end_date
loop
if res.start_date is not null and res.end_date is not null then
return next res;
elsif res.start_date is not null then
sd := res.start_date;
elsif res.end_date is not null then
res.start_date := sd;
return next res;
end if;
end loop;
return;
end;$body$
language 'plpgsql';
Então
select * from get_data() order by id, start_date;
retornou este resultado:
id | start_date | end_date
----+------------+------------
1 | 2011-01-01 | 2011-04-04
1 | 2011-06-06 | 2011-09-09
2 | 2011-01-01 | 2011-03-03
(3 rows)
que é, eu acho, o que você está procurando.