Přišel jsem pouze s dotazem CTE, protože problém je v tom, že může existovat řetězec překrývajících se časů, např. záznam 1 se překrývá se záznamem 2, záznam 2 se záznamem 3 a tak dále. To je těžké vyřešit bez CTE nebo jiného druhu smyček atd. Každopádně to zkuste.
První část dotazu CTE získá služby, které spouštějí novou skupinu a nemají stejný počáteční čas jako některá jiná služba (potřebuji mít pouze jeden záznam, který spouští skupinu). Ve druhé části jsou ti, kteří zakládají skupinu, ale je jich více než jedna se stejným časem začátku – opět potřebuji jen jednoho z nich. Poslední část rekurzivně navazuje na počáteční skupinu a bere všechny překrývající se služby.
Zde je SQLFiddle s více přidanými záznamy, které demonstrují různé druhy překrývajících se a duplicitních časů.
Nemohl jsem použít ServiceID
protože by musel být objednán stejným způsobem jako 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