Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Изравняване/сливане на припокриващи се интервали от време

Измислих само CTE заявка, тъй като проблемът е, че може да има верига от припокриващи се времена, напр. запис 1 се припокрива със запис 2, запис 2 със запис 3 и т.н. Това е трудно за разрешаване без CTE или някакъв друг вид вериги и т.н. Моля, опитайте все пак.

Първата част от CTE заявката получава услугите, които стартират нова група и нямат същото начално време като някои други услуги (трябва да имам само един запис, който стартира група). Втората част получава тези, които започват група, но има повече от един с едно и също начално време - отново имам нужда само от един от тях. Последната част рекурсивно се надгражда върху началната група, като взема всички припокриващи се услуги.

Ето SQLFiddle с още записи, добавени за демонстриране на различни видове припокриващи се и дублирани времена.

Не можах да използвам ServiceID тъй като трябва да се подреди по същия начин като 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. Използвайте TYPEPROPERTY() за връщане на информация за тип данни в SQL Server

  2. Мога ли да получа резултатите от съхранена процедура в курсор в друга съхранена процедура в SQL

  3. Извлечете>901 реда от SQL Server 2008 свързан сървър към Active Directory

  4. Как мога да посоча намек за индекс в Entity Framework?

  5. Как работи функцията STR() в SQL Server (T-SQL)