例如,我如何检查上午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的总休假时间。答案 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具有针对多个参数而不是多行的MIN
和MAX
个函数,那么后面的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语句中的第一个条件。