Tôi chỉ nghĩ ra một truy vấn CTE vì vấn đề là có thể có một chuỗi thời gian trùng lặp, ví dụ:bản ghi 1 chồng lên bản ghi 2, bản ghi 2 với bản ghi 3, v.v. Điều này khó có thể giải quyết được nếu không có CTE hoặc một số loại vòng lặp khác, v.v. Hãy tiếp tục.
Phần đầu tiên của truy vấn CTE nhận các dịch vụ bắt đầu một nhóm mới và không có cùng thời gian bắt đầu như một số dịch vụ khác (tôi chỉ cần có một bản ghi bắt đầu một nhóm). Phần thứ hai có những người bắt đầu một nhóm nhưng sau đó có nhiều hơn một người có cùng thời gian bắt đầu - một lần nữa, tôi chỉ cần một trong số họ. Phần cuối cùng xây dựng một cách đệ quy trên nhóm bắt đầu, lấy tất cả các dịch vụ chồng chéo.
Đây là SQLFiddle với nhiều bản ghi được thêm vào để chứng minh các loại thời gian trùng lặp và trùng lặp khác nhau.
Tôi không thể sử dụng ServiceID
vì nó sẽ phải được sắp xếp theo cách giống như 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