【问题标题】:Calculate elapsed time (DATEDIFF) while subtracting time for break and lunch periods计算经过时间 (DATEDIFF),同时减去休息和午餐时间
【发布时间】:2020-12-20 01:28:36
【问题描述】:

我有一个看起来像这样的表:

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

我需要以分钟为单位计算 start_timeend_time 之间的 elapsed_time,但如果 elapsed_time 跨越 8:45am9:00am 则减去 15 分钟和/或如果 elapsed_time 跨越 @ 则减去 30 分钟987654329@和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 并从那里手动计算。

【问题讨论】:

  • 请向我们展示您的尝试。
  • 如果时间段与两个固定范围重叠,比如从上午 8:50 到上午 11:40,该怎么办?
  • 如果发生这种情况,我希望它减去 15 分钟(8:45-8:50 为 5 分钟,11:30-11:40 为 10 分钟)
  • 我希望我可以说我有一个 excel 公式来计算 - 我正在手动计算。
  • 好吧,如果您考虑使用手动计算的逻辑,然后尝试将其转换为计算逻辑......这就是我解决任何问题的方式。

标签: sql sql-server tsql datediff


【解决方案1】:

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

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

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

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;

结果

job | start_time                | end_time                  | Total Mins    | Adjusted Mins
------------------------------------------------------------------------------------------
1   | 2020-08-31 09:46:00.000   | 2020-08-31 12:37:00.000   | 171           | 141
2   | 2020-08-31 09:54:00.000   | 2020-08-31 10:24:00.000   | 30            | 30
3   | 2020-08-31 05:52:00.000   | 2020-08-31 06:32:00.000   | 40            | 40
4   | 2020-08-31 05:02:00.000   | 2020-08-31 13:24:00.000   | 502           | 457

如果/当考虑到休息/午餐开始或结束的时间段时要考虑的事项:

  1. 如果时间段开始并且在一段时间内结束,则总分钟数应为零 - 这是一种特殊情况,一旦处理,您可以在其余逻辑中忽略。
  2. 如果在休息期间开始,则要减去的时间量是期间开始时间和休息结束时间之间的差。
  3. 如果您在休息期间的中途结束,那么要减去的时间量就是休息开始时间和期间结束时间之间的差异。

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

【讨论】:

  • 非常感谢!现在看一下判断何时/是否减去分钟的案例方法非常有意义。我很沮丧,在发布这个问题之前我没有想到这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-07
  • 2016-04-25
相关资源
最近更新 更多