简体   繁体   English

在规定的时间范围内计算分钟?

[英]Calculating minutes within a defined time window?

I am looking to calculate the minutes spent performing a task that is within a specific time window. 我正在计算在特定时间范围内执行任务所花费的时间。

I have the two input parameters defining the time window @WindowStart and @WindowEnd and i have [Task Start] and [Task End] columns in my task table. 我有两个输入参数,它们定义了时间窗口@WindowStart@WindowEnd并且在任务表中有[Task Start]和[Task End]列。

What would be the easiest way to calculate the time spent on a task that is within my time window? 计算在我的时间范围内的任务上花费的时间的最简单方法是什么? Tasks can easily begin or end after @WindowStart and @WindowEnd . 可以在@WindowStart@WindowEnd之后轻松地开始或结束任务。

If what you want is to find the length of tasks are entirely contained in the window: 如果要查找的任务长度完全包含在窗口中:

select [task end] - [task start] as taskDuration
from tasktable
where [task start] > @WindowStart and [task end] < @WindowEnd

If instead you want to look at durations that have any overlap with the window, just flip the and to an or. 相反,如果您要查看与窗口有任何重叠的持续时间,只需将和翻转为或。

This might work? 这可能有效吗? If the task start / end times are outside of the window start / end times, the difference would be negative. 如果任务的开始/结束时间不在窗口的开始/结束时间之内,则差异为负。 There are a few scenarios: 有以下几种情况:

select TestDates.*,
 DATEDIFF(minute, 
   CASE WHEN TestDates.WindowStart > TestDates.TaskStart 
        THEN TestDates.WindowStart ELSE TestDates.TaskStart END, 
   CASE WHEN TestDates.WindowEnd < TestDates.TaskEnd
        THEN TestDates.WindowEnd ELSE TestDates.TaskEnd END
         ) as Interval
 from
(
SELECT GETDATE() as WindowStart,
dateadd(minute, 10, GETDATE()) as WindowEnd,
dateadd(minute, 2, GETDATE()) as TaskStart,
dateadd(minute, 14, GETDATE()) as TaskEnd
) as TestDates


select TestDates.*,
 DATEDIFF(minute, 
   CASE WHEN TestDates.WindowStart > TestDates.TaskStart 
        THEN TestDates.WindowStart ELSE TestDates.TaskStart END, 
   CASE WHEN TestDates.WindowEnd < TestDates.TaskEnd
        THEN TestDates.WindowEnd ELSE TestDates.TaskEnd END
         ) as Interval
 from
(
SELECT GETDATE() as WindowStart,
dateadd(minute, 10, GETDATE()) as WindowEnd,
dateadd(minute, -2, GETDATE()) as TaskStart,
dateadd(minute, 20, GETDATE()) as TaskEnd
) as TestDates

select TestDates.*,
 DATEDIFF(minute, 
   CASE WHEN TestDates.WindowStart > TestDates.TaskStart 
        THEN TestDates.WindowStart ELSE TestDates.TaskStart END, 
   CASE WHEN TestDates.WindowEnd < TestDates.TaskEnd
        THEN TestDates.WindowEnd ELSE TestDates.TaskEnd END
         ) as Interval
 from
(
SELECT GETDATE() as WindowStart,
dateadd(minute, 10, GETDATE()) as WindowEnd,
dateadd(minute, 20, GETDATE()) as TaskStart,
dateadd(minute, 30, GETDATE()) as TaskEnd
) as TestDates

select TestDates.*,
 DATEDIFF(minute, 
   CASE WHEN TestDates.WindowStart > TestDates.TaskStart 
        THEN TestDates.WindowStart ELSE TestDates.TaskStart END, 
   CASE WHEN TestDates.WindowEnd < TestDates.TaskEnd
        THEN TestDates.WindowEnd ELSE TestDates.TaskEnd END
         ) as Interval
 from
(
SELECT GETDATE() as WindowStart,
dateadd(minute, 10, GETDATE()) as WindowEnd,
dateadd(minute, -20, GETDATE()) as TaskStart,
dateadd(minute, -10, GETDATE()) as TaskEnd
) as TestDates

Simply shift the start / end of the task to the appropriate limits. 只需将任务的开始/结束更改为适当的限制即可。 Mind that this requires that start-time comes before end-time, if any of the pairs is reversed you'll need to shift them around first or you'll get strange results. 请注意,这要求开始时间早于结束时间,如果任何一对反转,则需要先转移它们,否则会得到奇怪的结果。 Then again, when ever is end before start in the real world ? 再说一次,在现实世界开始之前什么时候结束? =) =)

DECLARE @task_start   datetime,
        @task_end     datetime,
        @window_start datetime,
        @window_end   datetime

SELECT @window_start = '09:00',
       @window_end   = '17:00',
       @task_start = '11:15',
       @task_end   = '19:22'

SELECT time_spent = (CASE WHEN @task_start > @window_end   THEN 0
                          WHEN @task_end   < @window_start THEN 0
                          ELSE DateDiff(minute, (CASE WHEN @task_start < @window_start THEN @window_start
                                                                                       ELSE @task_start END),
                                                (CASE WHEN @task_end > @window_end THEN @window_end
                                                                                   ELSE @task_end END))
                              END)

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

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