SQL-剔除周六日,节假日,非工作时间

需求是:求每个请求ID操作时间和验收时间之间的间隔,需要剔除周六日,节假日,非工作时间(我们的工作时间 09:00-17:30 午休时间12:00-13:00 午休时间不属于工作范围,需要剔除)

当看到这个需求的时候,就感觉让实现色彩斑斓的黑一样,整个人是没有思绪的

但是最后发现还是可以完成的

比如现有的数据:

这个表的字段意思:请求ID,操作时间,验收时间

实现这个功能需要两个表辅助:

第一个表:TB_IP_Times(该表就是存放每一天的日期)

第二个表:TB_IP_OAHrmPubHoliday(国家法定节假日表)

chagetype=1 的日期就是补班

changetype=2 的日期是正常假日

第一步:用日期表关联我们需要求的表,关联条件就是全部关联,然后筛选日期在我们的操作时间和结束时间范围内的日期,这里需要拼接一个当天的结束时间,还有开始时间和结束时间,后面有用

startDay:这段时间的开始时间(这里截取的是操作时间年月日作为开始时间)

endDay:这段时间的结束时间(这里截取的是验收时间年月日作为结束时间)

NowDay:就是这段时间的每一天,包括开始时间和结束时间

NowStartDay:就是NowDay拼接了每天的工作开始时间

NowEndDay:就是NowDay拼接了每天工作的结束时间

第二步:

这一步是为了判断这一天是否是开始时间,是否是结束时间,是否是周六日

如果非开始时间,非结束时间,那么我们的工作日期是7.5h

如果是开始时间,结束时间就需要更复杂的判断

isStartDay:1为是开始时间,0为不是

isEndDay:1为是结束时间,0为不是

isWeek:1为是周末,0为不是

第三步:

在节假日表中筛选补班的时间,因为如果周六日是补班的话,则周六日不剔除

第四步:

用第二步的视图,根据NowDay这个字段和补班的HolidayDate这个日期关联,如果可以关联上,则这一天的周六日是补班的,则修改isWeek这个字段状态=0

第五步:

筛选chageType=1的,即为真正放假的日期

第六步:

用temp4,根据NowDay去关联temp5,如果HolidayDate不为空的话,则需要修改isWeek状态,这里状态需要为1,因为放假日我们是不统计的,所以不统计的需要修改为1

比如如下:2020-06-25,2020-06-26原本是周四周五的,isweek状态是为0,需要统计的,但是这两天是端午节,属于节假日,不需要统计,所以我们将isweek状态从0修改为1

第七步:

这步骤需要稍微出来一下我们的操作时间和验收时间字段

当这两个字段小于操作当天的上班日期(09:00:00),则需要归为当天的上班时间

当这两个字段大于操作当天的午休开始时间(12:00:00),小于等于当天的午休结束时间(13:00:00)则需要归为当天的下午开始工作时间 13:00:00

这部分为了方便后面减时间

第八步:

这步骤就是最后一步了,

这里分几种情况:

第一种:如果是开始时间,不是结束时间,并且操作时间小于中午午休时间,那么我们用当天结束时间减去操作时间,再减去中间午休的一个小时(因为我这里使用的是时间戳,所以减去一小时就3600秒)

第二种:如果是开始时间,不是结束时间,并且操作时间大于下午工作时间,那么直接使用当天结束时间减去操作时间

第三种:如果是结束时间,不是开始时间,并且验收时间小于中午午休时间,那么我们用验收时间减去当天开始时间

第四种:如果是结束时间,不是开始时间,并且验收时间大于下午工作时间,那么使用验收结束时间减去当天开始时间,再减去中间午休的一个小时(因为我这里使用的是时间戳,所以减去一小时就3600秒)

第五种:如果当天是开始又是结束时间,且操作时间小于当天的午休开始时间,验收时间大于当天午休结束时间,那么需要用验收时间减去操作时间,再减去中间的午休时间

第六种:如果当天是开始又是结束时间,且不符合第五种的情况,就直接使用验收时间减去操作时间

其它情况就是 一整天的工作时长,就是7.5小时,然后使用7.5*3600转成秒

最后一步就是根据requestid分组,然后将Seconds求和就行了,得到就是这个时间范围之间相差的秒数,如果有需将秒要转天,小时,分钟,秒数可期待下一篇文章

如有不足,多多指教

猜你喜欢

转载自blog.csdn.net/happytjl/article/details/108256714