简体   繁体   English

事件的总持续时间,可能的间隙和间隔的重叠

[英]Total duration of events, possible gaps and overlaps in intervals

There is a list of time intervals. 有一个时间间隔列表。 There is always a start and end datetime, such as: 始终有一个开始和结束日期时间,例如:

TimeFrom                  TimeTill
2014-07-10 07:00:00.000   2014-07-10 11:30:00.000
2014-07-10 13:00:00.000   2014-07-10 14:00:00.000
2014-07-10 13:00:00.000   2014-07-10 14:30:00.000

Both TimeFrom and TimeTill are always on the same day, no exceptions. TimeFromTimeTill都在同一天,没有例外。 Let`s assume this represents time spent working on different projects (three in this case). 我们假设这代表了在不同项目上工作的时间(在这种情况下为三个)。 Overlaps are allowed. 允许重叠。

I would like to kindly ask for help with a SQL Server 2008 R2 query to get me the total length of time the person spent working during the day. 我想请求SQL Server 2008 R2查询的帮助,以获得该人在白天工作的总时间。

Please note that there is a period of no work. 请注意,有一段时间没有工作。 In this case, it is between 11:30 and 13:00. 在这种情况下,它是在11:30和13:00之间。

When I use a min(TimeFrom) and max(TimeTill) to calculate the duration between the earliest start and latest finish, it works just fine for the overlaps, except that I am unable to subtract the interval of no work. 当我使用min(TimeFrom)max(TimeTill)来计算最早开始和最后完成之间的持续时间时,它对重叠起作用很好,除了我无法减去没有工作的间隔。

A desired output is something along this line: 所需的输出就是这条线:

Day         TimeWorking
2014-07-10  360

Your help is greatly appreciated! 非常感谢您的帮助!

Paul 保罗

You can build a list of 1 minute intervals for an entire day. 您可以构建一整天的1分钟间隔列表。 An exists query can filter out minutes without work. exists查询可以过滤掉分钟而无需工作。 The resulting count is the number of minutes for which work was done: 结果计数是完成工作的分钟数:

; with  all_minutes as
        (
        select  cast('00:00' as time) as time
        union all
        select  dateadd(minute, 1, time)
        from    all_minutes
        where   time < cast('23:59' as time)
        )
select  cast(yt.TimeFrom as date) as day
,       count(distinct am.time) as minutes_worked
from    YourTable yt
left join
        all_minutes am
on      cast(yt.TimeFrom as time) <= am.time
        and am.time < cast(yt.TimeTo as time)
group by
        cast(TimeFrom as date)
option  (maxrecursion 0)
;

Example at SQL Fiddle. SQL Fiddle的例子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM