sql >> Databáze >  >> RDS >> Sqlserver

Narovnat/sloučit překrývající se časové intervaly

Přišel jsem pouze s dotazem CTE, protože problém je v tom, že může existovat řetězec překrývajících se časů, např. záznam 1 se překrývá se záznamem 2, záznam 2 se záznamem 3 a tak dále. To je těžké vyřešit bez CTE nebo jiného druhu smyček atd. Každopádně to zkuste.

První část dotazu CTE získá služby, které spouštějí novou skupinu a nemají stejný počáteční čas jako některá jiná služba (potřebuji mít pouze jeden záznam, který spouští skupinu). Ve druhé části jsou ti, kteří zakládají skupinu, ale je jich více než jedna se stejným časem začátku – opět potřebuji jen jednoho z nich. Poslední část rekurzivně navazuje na počáteční skupinu a bere všechny překrývající se služby.

Zde je SQLFiddle s více přidanými záznamy, které demonstrují různé druhy překrývajících se a duplicitních časů.

Nemohl jsem použít ServiceID protože by musel být objednán stejným způsobem jako 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. Optimální velikost pro databázové oddíly

  2. MySQL:Můžete určit náhodný limit?

  3. schéma databáze přátelství

  4. Jak spustit skript .sql z bash