Wymyśliłem tylko zapytanie CTE, ponieważ problemem może być łańcuch nakładających się czasów, np. rekord 1 pokrywa się z rekordem 2, rekord 2 z rekordem 3 i tak dalej. Jest to trudne do rozwiązania bez CTE lub innego rodzaju pętli itp. Proszę spróbować.
Pierwsza część zapytania CTE pobiera usługi, które uruchamiają nową grupę i nie mają tego samego czasu rozpoczęcia, co inne usługi (potrzebuję tylko jednego rekordu, który uruchamia grupę). Druga część obejmuje tych, którzy rozpoczynają grupę, ale jest ich więcej niż jedna z tym samym czasem rozpoczęcia - znowu potrzebuję tylko jednego z nich. Ostatnia część rekursywnie buduje się na grupie początkowej, biorąc wszystkie nakładające się usługi.
Oto SQLFiddle z większą liczbą dodanych rekordów, aby zademonstrować różne rodzaje nakładania się i duplikowania czasów.
Nie mogłem użyć ServiceID
ponieważ musiałby być zamawiany w taki sam sposób jak 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