Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Làm phẳng / hợp nhất các khoảng thời gian chồng chéo

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Phát hiện khoảng thời gian bất thường bằng SQL

  2. Mọi khóa ngoại của SQL Server có nên có một chỉ mục phù hợp không?

  3. Cách tham gia vào hàng đầu tiên

  4. Tạo một mô hình khung thực thể mở rộng nhiều cơ sở dữ liệu

  5. Trước tiên, cách thay đổi / đặt đối chiếu trong EF Code