Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Ratakan/gabungkan interval waktu yang tumpang tindih

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dukungan Dialek SQL 2008 untuk NHibernate

  2. SQL Server menggunakan wildcard dalam IN

  3. Bergabunglah dengan dua tabel, hanya gunakan nilai terbaru dari tabel kanan

  4. Versi SQL Server mana yang didukung LINQ to SQL?

  5. Denormalisasi Data (Mungkin Pivot?)