Eu só criei uma consulta CTE, pois o problema é que pode haver uma cadeia de tempos sobrepostos, por exemplo. o registro 1 se sobrepõe ao registro 2, o registro 2 ao registro 3 e assim por diante. Isso é difícil de resolver sem CTE ou algum outro tipo de loop, etc. Por favor, tente de qualquer maneira.
A primeira parte da consulta CTE obtém os serviços que iniciam um novo grupo e não têm o mesmo horário de início de algum outro serviço (preciso ter apenas um registro que inicie um grupo). A segunda parte recebe aqueles que iniciam um grupo, mas há mais de um com o mesmo horário de início - novamente, preciso de apenas um deles. A última parte se acumula recursivamente no grupo inicial, tomando todos os serviços sobrepostos.
Aqui está SQLFiddle com mais registros adicionados para demonstrar diferentes tipos de tempos sobrepostos e duplicados.
Não consegui usar
ServiceID
pois teria que ser ordenado da mesma forma que 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