Dette er ret kompliceret. Her er en tilgang, der bruger vinduesfunktioner.
Brug først datotabellen til at opregne datoerne uden weekender (du kan også holde ferie, hvis du vil). Udvid derefter perioderne til én dag pr. række ved at bruge en non-equijoin.
Du kan derefter bruge et trick til at identificere sekventielle dage. Dette trick er at generere et fortløbende tal for hvert id og trække det fra det fortløbende tal for datoerne. Dette er en konstant for sekventielle dage. Det sidste trin er blot en sammenlægning.
Den resulterende forespørgsel er noget som dette:
with d as (
select d.*, row_number() over (order by date) as seqnum
from dates d
where day not in ('Saturday', 'Sunday')
)
select t.id, min(t.date) as startdate, max(t.date) as enddate, sum(duration)
from (select t.*, ds.seqnum, ds.date,
(d.seqnum - row_number() over (partition by id order by ds.date) ) as grp
from table t join
d ds
on ds.date between t.startdate and t.enddate
) t
group by t.id, grp;
EDIT:
Følgende er versionen på dette SQL Fiddle:
with d as (
select d.*, row_number() over (order by date) as seqnum
from datetable d
where day not in ('Saturday', 'Sunday')
)
select t.id, min(t.date) as startdate, max(t.date) as enddate, sum(duration)
from (select t.*, ds.seqnum, ds.date,
(ds.seqnum - row_number() over (partition by id order by ds.date) ) as grp
from (select t.*, 'abc' as id from table1 t) t join
d ds
on ds.dateid between t.startdate and t.enddate
) t
group by grp;
Jeg tror, det virker, men datotabellen indeholder ikke alle datoerne.