计算开始结束日期的非重叠总持续时间

时间:2012-08-16 07:27:17

标签: sql sql-server

我有一个带有Begindate(datetime)和Enddate(datetime)的数据库表。该表包含活动持续时间。现在我正在尝试创建一个函数来根据指定的begindate-enddate中的非重叠活动计算总持续时间。

一个例子如下:

我正在调用这个函数给出参数: Begindate ='2012-08-16 10:00' Enddate ='2012-08-16 18:00'

现在让我们说下表中的数据如下:

  1. 开始:'2012-08-15 10:00'结束'2012-08-15 14:00'(总共4小时)
  2. 开始:'2012-08-16 09:00'结束'2012-08-16 11:00'(总共2小时)
  3. 开始:'2012-08-16 10:30'结束'2012-08-16 10:45'(总共15分钟)
  4. 开始:'2012-08-16 12:00'结束'2012-08-16 16:00'(总共4小时)
  5. 开始:'2012-08-16 13:00'结束'2012-08-16 17:00'(总共4小时)
  6. 开始:'2012-08-16 16:30'结束'2012-08-16 16:45'(共15分钟)
  7. 开始:'2012-08-16 17:30'结束'2012-08-16 20:00'(总共2小时30分钟)
  8. 现在我希望以下情况发生:

    1. 第一项活动在指定期间之外,因此不会包括在内。
    2. 部分匹配,所以这将返回1小时。
    3. 活动在第二个活动中,因此不会包括在内。
    4. 将包含4个小时的期限。
    5. 从16:00到17:00将包括1小时
    6. 不包括活动。
    7. 指定时间段内只有30分钟,因此将包括在内。
    8. 返回的总数将是:6小时30分钟。

      如果有人能帮助我,我将非常感激! :)

1 个答案:

答案 0 :(得分:3)

计算缺失范围可能更容易,然后从完整期间减去持续时间:

declare @begindate datetime = '20120816 10:00:00'
declare @enddate datetime = '20120816 18:00:00'

; with supplement as (
  select begindate, enddate
    from daterangetable
      -- overlapping ranges only
   where begindate <= @enddate
     and enddate >= @begindate
  union all
  -- empty start range to catch missing start intervals
  select @begindate, @begindate
  union all
  -- empty end range to catch missing end intervals
  select @enddate, @enddate
)
select datediff (minute, @begindate, @enddate)
     - sum (datediff (minute, gapStart, gapEnd)) Minutes
from
(
  select max(d2.enddate) gapStart, 
         d1.begindate gapEnd
    from supplement d1
   cross join supplement d2
      -- d2 range must start before d1 range
   where d2.begindate < d1.begindate
   group by d1.begindate
      -- Range is completely covered if d2 ends after d1 begins
      -- so it should be removed
  having max(d2.enddate) < d1.begindate
) missingRanges

Two ranges overlap如果第一个的结束是在第二个的开始之后,并且第一个的开始是在第二个的结束之前。请参阅链接(更好)解释。

如果您没有使用Sql Server 2005或更新版本,则需要将with内的代码移动到派生表中以获取补充d1和补充d2。

And here is Sql Fiddle with example

相关问题