计算总时间而不会重叠

时间:2019-04-20 07:30:02

标签: sql sql-server

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

import CircleCheckBox, {LABEL_POSITION} from 'react-native-circle-checkbox';

        {this.state.currentTab === 1 && (
                  <View>
                    <CircleCheckBox
              checked={true}
              onToggle={(text) => this.setGender(true)}
              labelPosition={LABEL_POSITION.RIGHT}
              label="MALE"
            />    
    <CircleCheckBox
              checked={true}
              onToggle={(text) => this.setGender(false)}
              labelPosition={LABEL_POSITION.RIGHT}
              label="FEMALE"
            />  
                  </View>
                )}

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

表1的工作时间

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

Table2叶子

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

并通过表1(工作时间)找到每天无重叠的总休假时间(我的意思是计算休假时间(来自表2)-工作时间(表1))

这是我需要的结果:

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

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

1 个答案:

答案 0 :(得分:2)

您的计算不清楚。在第三行中,您指定了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 <>小提琴。

这比大多数此类问题要棘手,因为您不希望重叠,而是希望剩下的部分。这需要考虑工作时间的“之前”和“之后”情况。