sql >> Databasteknik >  >> RDS >> Sqlserver

Platta ut/sammanfoga överlappande tidsintervall

Jag kom bara med en CTE-fråga eftersom problemet är att det kan finnas en kedja av överlappande tider, t.ex. post 1 överlappar med post 2, post 2 med post 3 och så vidare. Detta är svårt att lösa utan CTE eller någon annan typ av loopar, etc. Snälla prova det ändå.

Den första delen av CTE-frågan får de tjänster som startar en ny grupp och som inte har samma starttid som någon annan tjänst (jag behöver bara ha en post som startar en grupp). Den andra delen får de som startar en grupp men det finns fler än en med samma starttid - igen, jag behöver bara en av dem. Den sista delen bygger rekursivt upp på startgruppen och tar alla överlappande tjänster.

Här är SQLFiddle med fler poster tillagda för att demonstrera olika typer av överlappande och duplicerade tider.

Jag kunde inte använda ServiceID eftersom det skulle behöva beställas på samma sätt 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. PDO::ERRMODE_EXCEPTION undertrycker inte varning

  2. Returnera alla rader från en specifik partition i SQL Server (T-SQL)

  3. MySQL-uppdateringssatsen matchar endast den första raden

  4. Exempel på PHP + MySQL-transaktioner