sql >> Database >  >> RDS >> Sqlserver

Overlappende tijdsintervallen afvlakken/samenvoegen

Ik heb alleen een CTE-query bedacht omdat het probleem is dat er een reeks overlappende tijden kan zijn, b.v. record 1 overlapt met record 2, record 2 met record 3 enzovoort. Dit is moeilijk op te lossen zonder CTE of een ander soort lussen, enz. Probeer het toch.

Het eerste deel van de CTE-query haalt de services op die een nieuwe groep starten en die niet dezelfde starttijd hebben als een andere service (ik heb slechts één record nodig waarmee een groep wordt gestart). Het tweede deel krijgt degenen die een groep beginnen, maar er is meer dan één met dezelfde starttijd - nogmaals, ik heb er maar één nodig. Het laatste deel bouwt recursief op de startgroep op en neemt alle overlappende diensten.

Hier is SQLFiddle met meer records toegevoegd om verschillende soorten overlappende en dubbele tijden aan te tonen.

Ik kon ServiceID niet gebruiken omdat het op dezelfde manier moet worden besteld als 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. Decimaal VS Int in MySQL?

  2. Kan ik Django F()-objecten gebruiken met tekenreeksaaneenschakeling?

  3. Waarom wordt de MySQL-verbinding geblokkeerd door veel verbindingsfouten?

  4. Hoe maak je programmatisch een ODBC-gekoppelde tabel aan een SQL Server-weergave en bewerkbaar?