Saya hanya membuat kueri CTE karena masalahnya mungkin ada rantai waktu yang tumpang tindih, mis. catatan 1 tumpang tindih dengan catatan 2, catatan 2 dengan catatan 3 dan seterusnya. Ini sulit untuk diselesaikan tanpa CTE atau jenis loop lainnya, dll. Silakan coba saja.
Bagian pertama dari kueri CTE mendapatkan layanan yang memulai grup baru dan tidak memiliki waktu mulai yang sama dengan beberapa layanan lain (saya hanya perlu memiliki satu catatan yang memulai grup). Bagian kedua mendapatkan orang-orang yang memulai grup tetapi ada lebih dari satu dengan waktu mulai yang sama - sekali lagi, saya hanya perlu salah satunya. Bagian terakhir secara rekursif dibangun di grup awal, mengambil semua layanan yang tumpang tindih.
Ini SQLFiddle dengan lebih banyak catatan yang ditambahkan untuk menunjukkan berbagai jenis waktu yang tumpang tindih dan duplikat.
Saya tidak dapat menggunakan ServiceID
karena harus dipesan dengan cara yang sama seperti 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