sql >> Database teknologi >  >> RDS >> Sqlserver

Udjævn/flet overlappende tidsintervaller

Jeg kom kun med en CTE-forespørgsel, da problemet er, at der kan være en kæde af overlappende tidspunkter, f.eks. rekord 1 overlapper med rekord 2, rekord 2 med rekord 3 og så videre. Dette er svært at løse uden CTE eller en anden form for loops osv. Prøv det alligevel.

Den første del af CTE-forespørgslen får de tjenester, der starter en ny gruppe, og som ikke har samme starttidspunkt som en anden tjeneste (jeg skal kun have én post, der starter en gruppe). Den anden del får dem, der starter en gruppe, men der er mere end én med samme starttidspunkt - igen, jeg har kun brug for én af dem. Den sidste del bygger rekursivt op på startgruppen og tager alle overlappende tjenester.

Her er SQLFiddle med flere registreringer tilføjet for at demonstrere forskellige former for overlappende og dubletter.

Jeg kunne ikke bruge ServiceID da det skulle bestilles på samme måde som 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. Få et specifikt datointerval

  2. Simple Encrypted Arithmetic Library (SEAL) og segl::Ciphertext-variablen

  3. Sådan får du en liste over oprindelige Oracle-funktioner som (NVL, ABS osv.)

  4. PhpStorm kunne ikke løse kolonne for flere databaseforbindelser