检查时间范围是否在另一个时间范围之间

时间:2015-01-21 06:51:38

标签: sql-server

我坚持不懈地解决问题。如何检查时间范围是否在另一个时间范围之间?

例如,我如何检查上午11:00至中午12:00是否在上午9:30至下午2:00之间? 我在开发计时系统时需要这个,以检查员工的病假是否包括他预定的休息时间。

我正在使用SQL Server 2008

declare @timefrom datetime
declare @timeto datetime
declare @timefromBreak datetime
declare @timetoBreak datetime

set @timefrom = cast('01/21/2015 11:30:00' as datetime)
set @timeto = cast('01/21/2015 14:00:00' as datetime)
set @timefromBreak = cast('01/21/2015 11:00:00' as datetime)
set @timetoBreak = cast('01/21/2015 12:00:00' as datetime)

select 
case when ((@timefromBreak between @timefrom and @timeto) AND (@timetoBreak between @timefrom and @timeto)) then
(datediff(hour, @timefrom,@timeto) - datediff(hour,@timefromBreak,@timetoBreak))

else datediff(hour, @timefrom,@timeto) 

end as TotalLeaveHours

这是我的例子..我试图获得员工提出休假的总休假时间。

逻辑是,我将得到不包括休息时间的总休假时间(当且仅当休假时间范围涵盖休息时间时。)

因此,如果员工在晚上11:30到下午2:00提出休假,他的预定休息时间是晚上11:00到12:00。总休假时间应为2小时。

上午11:30至中午12:00不应计入自预定时间为上午11:00至中午12:00的总休假时间。

2 个答案:

答案 0 :(得分:1)

这计算时差(当前 1 的分钟数)并尝试处理所有可能的重叠:

declare @timefrom datetime
declare @timeto datetime
declare @timefromBreak datetime
declare @timetoBreak datetime

select @timefrom = '2015-01-21T11:30:00',@timeto = '2015-01-21T14:00:00',
       @timefromBreak = '2015-01-21T11:00:00',@timetoBreak = '2015-01-21T12:00:00'

select DATEDIFF(minute,@timefrom,@timeto) -
CASE WHEN @timeFrom < @timeToBreak AND @timefromBreak < @timeTo THEN
    DATEDIFF(minute,
        CASE WHEN @timeFrom > @timeFromBreak THEN @timeFrom ELSE @timeFromBreak END,
        CASE WHEN @timeTo < @timeToBreak THEN @timeTo ELSE @timeToBreak END
    ) ELSE 0 END

希望您可以看到基本逻辑 - 我们总是计算时差 - 然后我们检查是否存在重叠。只有存在重叠时我们才需要调整总时间,并且我们使用几个CASE表达式来解释当休息时间和休假时间部分重叠或完全重叠时重叠。

(如果SQL Server具有针对多个参数而不是多行的MINMAX个函数,那么后面的CASE表达式就是MAX(@timeFrom,@timeFromBreak)和{ {1}})


1 因为在你的一些例子中,你似乎正在使用例如2.5小时,我虽然在几分钟内工作更安全,让你作为最后一步进行任何最终调整/舍入/向上,与这些计算分开

答案 1 :(得分:0)

4是总休假时间..

很抱歉让我感到困惑..我需要得到总小时数。我试过了,我认为如果休假时间范围将涵盖整个休息时间,将不会有冲突。如果只是部分休息时间将被覆盖,第一个条件将是假的..

如果员工的休息时间是上午11:00到中午12:00,那么他提交的请假是从上午11:30到下午2:00,总休假时间应该只返回3小时,而不是2.5小时。

在我的测试中,

    declare @timefrom datetime
declare @timeto datetime
declare @timefromBreak datetime
declare @timetoBreak datetime

set @timefrom = cast('01/21/2015 11:30:00' as datetime)
set @timeto = cast('01/21/2015 14:00:00' as datetime)
set @timefromBreak = cast('01/21/2015 11:00:00' as datetime)
set @timetoBreak = cast('01/21/2015 12:00:00' as datetime)

select 
case when ((@timefromBreak between @timefrom and @timeto) AND (@timetoBreak between @timefrom and @timeto)) then
(datediff(hour, @timefrom,@timeto) - datediff(hour,@timefromBreak,@timetoBreak))

else datediff(hour, @timefrom,@timeto) 

end as TotalLeaveHours

这会返回3个小时,因为它不符合Select Case语句中的第一个条件。