计算不重叠的总时间[关闭]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算不重叠的总时间[关闭]相关的知识,希望对你有一定的参考价值。

标准工作时间是从08:00开始,到16:00结束,所以我为此声明了2个参数:

DECLARE @StartTime TIME = '08:00',
        @EndTime TIME = '16:00'

所有时间计算必须在开始和结束时间之间。

表1工作时间

Id      Date        WorkStartTime     WorkEndTime
-------------------------------------------------------
 1   2019/04/20     08:30            14:20
 2   2019/04/21     09:05            15:15
 3   2019/04/22     08:37            14:22
 4   2019/04/23     08:05            15:00

表2叶子

Id      Date       LeaveStartTime   LeaveEndTime    
--------------------------------------------------------
 1   2019/04/20     08:00            09:00      
 2   2019/04/21     08:30            16:00
 3   2019/04/22     07:00            08:45
 4   2019/04/22     14:20            17:00

并且按表1(工作时间)查找每天的总休假时间而不重叠(我的意思是计算休假时间(来自表2) - 工作时间(表1))

这是我需要的结果:

2019/04/20  30 min 
2019/04/21  80 min -- (35' at first and 45' at end)
2019/04/22  98 min -- (calculate 14:22(workendtime bigger than lavestarttime)   to 16:00 (for @EndTime))

我希望在SQL查询中执行此操作。我正在使用SQL Server 2016

答案

你的计算不清楚。对于第三行,您指定98分钟,但这会在一天开始时遗漏37分钟。

您可以在SQL Server中执行此计算。重叠的时间段有点乱,但在SQL中肯定是可能的。

以下是我认为你想要的逻辑:

select l.date,
       sum(datediff(minute, l.LeaveStartTime,
                    (case when l.LeaveStartTime < w.workStartTime then w.workStartTime else l.LeaveStartTime end)
                   ) +
           datediff(minute,
                    (case when l.LeaveEndTime > w.workEndTime then w.workEndTime else l.LeaveEndTime end),
                    l.LeaveEndTime
                   )
          ) as overlaps
from (select l.d, l.date,
             (case when LeaveStartTime < '08:00' then '08:00' else LeaveStartTime end) as LeaveStartTime,
             (case when LeaveEndTime > '16:00' then '16:00' else LeaveEndTime end) as LeaveEndTime
      from leaves l
      where LeaveEndTime > '08:00' and LeaveStartTime < '16:00'
     ) l join
     works w
     on w.date = l.date and
        (l.LeaveStartTime < w.WorkStartTime or
         l.leaveEndTime > w.workEndTime
        )
group by l.date;

Here是一个db <>小提琴。

这比大多数这样的问题更棘手,因为你不想要重叠 - 你想要留下的碎片。这需要考虑工作时间的“之前”和“之后”情况。

以上是关于计算不重叠的总时间[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

片段与另一个片段重叠

如何修复重叠的片段

DrawerLayout 重叠片段

计算java中月份和年份的总天数[关闭]

查找处理多个作业/订单的总时间,每个工人和作业/订单的重叠/重叠时间

导航上的片段生命周期重叠