Ik heb alleen een CTE-query bedacht omdat het probleem is dat er een reeks overlappende tijden kan zijn, b.v. record 1 overlapt met record 2, record 2 met record 3 enzovoort. Dit is moeilijk op te lossen zonder CTE of een ander soort lussen, enz. Probeer het toch.
Het eerste deel van de CTE-query haalt de services op die een nieuwe groep starten en die niet dezelfde starttijd hebben als een andere service (ik heb slechts één record nodig waarmee een groep wordt gestart). Het tweede deel krijgt degenen die een groep beginnen, maar er is meer dan één met dezelfde starttijd - nogmaals, ik heb er maar één nodig. Het laatste deel bouwt recursief op de startgroep op en neemt alle overlappende diensten.
Hier is SQLFiddle met meer records toegevoegd om verschillende soorten overlappende en dubbele tijden aan te tonen.
Ik kon ServiceID
niet gebruiken omdat het op dezelfde manier moet worden besteld als BeginTime
.
;with flat as
(
select StaffID, ServiceDate, BeginTime, EndTime, BeginTime as groupid
from services S1
where not exists (select * from services S2
where S1.StaffID = S2.StaffID
and S1.ServiceDate = S2.ServiceDate
and S2.BeginTime <= S1.BeginTime and S2.EndTime <> S1.EndTime
and S2.EndTime > S1.BeginTime)
union all
select StaffID, ServiceDate, BeginTime, EndTime, BeginTime as groupid
from services S1
where exists (select * from services S2
where S1.StaffID = S2.StaffID
and S1.ServiceDate = S2.ServiceDate
and S2.BeginTime = S1.BeginTime and S2.EndTime > S1.EndTime)
and not exists (select * from services S2
where S1.StaffID = S2.StaffID
and S1.ServiceDate = S2.ServiceDate
and S2.BeginTime < S1.BeginTime
and S2.EndTime > S1.BeginTime)
union all
select S.StaffID, S.ServiceDate, S.BeginTime, S.EndTime, flat.groupid
from flat
inner join services S
on flat.StaffID = S.StaffID
and flat.ServiceDate = S.ServiceDate
and flat.EndTime > S.BeginTime
and flat.BeginTime < S.BeginTime and flat.EndTime < S.EndTime
)
select StaffID, ServiceDate, MIN(BeginTime) as begintime, MAX(EndTime) as endtime
from flat
group by StaffID, ServiceDate, groupid
order by StaffID, ServiceDate, begintime, endtime