Sql 计算运行时间(DATEDIFF),同时减去休息和午餐时间

Sql 计算运行时间(DATEDIFF),同时减去休息和午餐时间,sql,sql-server,tsql,datediff,Sql,Sql Server,Tsql,Datediff,我有一张桌子,看起来像: job | start_time | end_time ---------------------------------------------------------- 1 | 2020-08-31 09:46:00.000 | 2020-08-31 12:37:00.000 2 | 2020-08-31 09:54:00.000 | 2020-08-31 10:24:00.000 3 | 2020-08-31 05:

我有一张桌子,看起来像:

job | start_time               | end_time
----------------------------------------------------------
1   | 2020-08-31 09:46:00.000  |  2020-08-31 12:37:00.000
2   | 2020-08-31 09:54:00.000  |  2020-08-31 10:24:00.000
3   | 2020-08-31 05:52:00.000  |  2020-08-31 06:32:00.000
4   | 2020-08-31 05:02:00.000  |  2020-08-31 13:24:00.000
我需要计算
开始时间
结束时间
之间的
已用时间
以分钟为单位,但如果
已用时间
跨越
8:45am
9:00am
和/或
已用时间
跨越
11:30am
12:00pm

输出应如下所示:

job | start_time               | end_time                 | elapsed_time
-------------------------------------------------------------------------
1   | 2020-08-31 09:46:00.000  |  2020-08-31 12:37:00.000 | 141
2   | 2020-08-31 09:54:00.000  |  2020-08-31 10:24:00.000 | 30
3   | 2020-08-31 05:52:00.000  |  2020-08-31 06:32:00.000 | 40
4   | 2020-08-31 05:02:00.000  |  2020-08-31 13:24:00.000 | 457
谢谢你的帮助

编辑:

我目前使用以下公式计算分钟数:

SELECT DATEDIFF(minute, start_time, end_time) FROM jobtran

然后将数据集导出到excel并从中手动计算。

以下内容返回所显示样本数据的所需结果。但是,它假定一个时间段始终在一天之内。它假设在休息时间内没有时间段开始或结束(我将把它作为练习留给你)

诀窍是使用表达式来检测何时发生重叠并进行调整

还请注意,使用子查询/派生表可以避免在整个查询中重复相同的转换和静态值

declare @Test table (job int, start_time datetime, end_time datetime);

insert into @Test (job, start_time, end_time)
values
(1, '2020-08-31 09:46:00.000',  '2020-08-31 12:37:00.000'),
(2, '2020-08-31 09:54:00.000',  '2020-08-31 10:24:00.000'),
(3, '2020-08-31 05:52:00.000',  '2020-08-31 06:32:00.000'),
(4, '2020-08-31 05:02:00.000',  '2020-08-31 13:24:00.000');

select job, start_time, end_time
  , datediff(minute, start_time, end_time) [Total Mins]
  , datediff(minute, start_time, end_time)
  - case when start_time < end_break and end_time > start_break then 15 else 0 end
  - case when start_time < end_lunch and end_time > start_lunch then 30 else 0 end [Adjusted Mins]
from (
  select job
    , convert(time, start_time) start_time
    , convert(time, end_time) end_time
    , convert(time, '08:45am') start_break
    , convert(time, '09:00am') end_break
    , convert(time, '11:30am') start_lunch
    , convert(time, '12:00pm') end_lunch
  from @Test
) X;
如果考虑到在休息/午餐开始或结束的时间段,要考虑的事情:

  • 如果某个时间段在某个时间段内开始和结束,则总分钟数应为零-这是一种特殊情况,一旦处理完毕,您可以在逻辑的其余部分忽略
  • 如果开始时间在中断时间的一半,则要减去的时间量是中断时间开始时间和中断结束时间之间的差值
  • 如果在中断期间中途结束,则要减去的时间量是中断开始时间和期间结束时间之间的差值

  • 注意:如果您以后像这样设置示例数据,您将更快地获得帮助。

    下面返回所显示示例数据的所需结果。但是,它假定一个时间段始终在一天之内。它假设在休息时间内没有时间段开始或结束(我将把它作为练习留给你)

    诀窍是使用表达式来检测何时发生重叠并进行调整

    还请注意,使用子查询/派生表可以避免在整个查询中重复相同的转换和静态值

    declare @Test table (job int, start_time datetime, end_time datetime);
    
    insert into @Test (job, start_time, end_time)
    values
    (1, '2020-08-31 09:46:00.000',  '2020-08-31 12:37:00.000'),
    (2, '2020-08-31 09:54:00.000',  '2020-08-31 10:24:00.000'),
    (3, '2020-08-31 05:52:00.000',  '2020-08-31 06:32:00.000'),
    (4, '2020-08-31 05:02:00.000',  '2020-08-31 13:24:00.000');
    
    select job, start_time, end_time
      , datediff(minute, start_time, end_time) [Total Mins]
      , datediff(minute, start_time, end_time)
      - case when start_time < end_break and end_time > start_break then 15 else 0 end
      - case when start_time < end_lunch and end_time > start_lunch then 30 else 0 end [Adjusted Mins]
    from (
      select job
        , convert(time, start_time) start_time
        , convert(time, end_time) end_time
        , convert(time, '08:45am') start_break
        , convert(time, '09:00am') end_break
        , convert(time, '11:30am') start_lunch
        , convert(time, '12:00pm') end_lunch
      from @Test
    ) X;
    
    如果考虑到在休息/午餐开始或结束的时间段,要考虑的事情:

  • 如果某个时间段在某个时间段内开始和结束,则总分钟数应为零-这是一种特殊情况,一旦处理完毕,您可以在逻辑的其余部分忽略
  • 如果开始时间在中断时间的一半,则要减去的时间量是中断时间开始时间和中断结束时间之间的差值
  • 如果在中断期间中途结束,则要减去的时间量是中断开始时间和期间结束时间之间的差值

  • 注意:如果您以后像这样设置示例数据,您将获得更快的帮助。

    请向我们展示您的尝试。如果时间段与两个固定范围重叠,例如从上午8:50到上午11:40,该怎么办?如果发生这种情况,我希望它减去15分钟(8:45-8:50减去5分钟,11:30-11:40减去10分钟)我希望我可以说我有一个Excel公式来计算-我是手动计算的。如果你考虑你正在使用的逻辑来手动计算它,那么试着把它转换成计算逻辑…这就是我处理任何问题的方法。请告诉我们您的尝试。如果周期与两个固定范围重叠,比如从上午8:50到上午11:40,该怎么办?如果发生这种情况,我希望它减去15分钟(8:45-8:50减去5分钟,11:30-11:40减去10分钟)我希望我可以说我有一个Excel公式来计算-我是手动计算的。如果你考虑你正在使用的逻辑来手动计算它,那么试着把它转换成计算逻辑…这就是我解决任何问题的方法。非常感谢!现在来看一下,确定何时/是否减去分钟的case方法非常有意义。我很沮丧在发布这个问题之前我没有想到这一点。非常感谢!现在来看一下,确定何时/是否减去分钟的case方法非常有意义。我很沮丧,我在发布这个问题之前没有想到这一点。