2015-01-21 229 views
0

我一直在解决一些事情。我如何检查时间范围是否在另一个时间范围之间?检查时间范围是否在另一个时间范围

例如,我如何检查11:00 AM - 12:00 PM是在9:30 AM - 2PM之间? 我需要这个开发计时系统来检查员工的病假是否涵盖他的计划休息时间。使用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 PM到下午2点,他的预定休息时间是从11:00到12:00。总休假时间应该只有2个小时。

上午11:30至下午12:00不应该算对,因为他的计划的总时间休假时间为上午11:00至下午12:00 ..

+1

您的表格是什么样的?什么是数据和你期望的输出?最重要的是你尝试过什么? – 2015-01-21 07:17:06

+0

确定重叠有一个非常简单的规则 - 两个时间段重叠,如果第一个在第二个结束之前开始*和*第二个在第一个结束之前开始 - 但是,根据您发布的答案,实际上是试图围绕重叠进行一些计算 - 所以你可以编辑你的问题并添加一些示例数据和预期结果 - 我们不需要很多,但是多于一个*单个的例子可能是有益的。 – 2015-01-21 07:51:30

+0

谢谢,我会.. – 2015-01-21 08:03:14

回答

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)MIN(@timeTo,@timeToBreak)


由于一些你似乎正在与你合作的例子2。5小时,我认为在几分钟内工作会更安全,并让您进行最终调整/向下/向上作为最后一步,与这些计算分开

+0

然后我会把它分成60以获得小时?我将@timefrom更改为'2015-01-21T09:30:00',我得到的是整数3而不是3.5(带小数) – 2015-01-21 08:18:44

+0

@bob_tiamsic - 如果将当前结果除以60(整数除法)你会得到几个小时,但你会失去任何小数部分(例如150/60 = 2),我不确定这是你的总体预期结果,或者你是想保留小数部分还是总计 – 2015-01-21 08:20:54

+0

得到它!试图投(作为小数(3,2))非常感谢你!这是非常有帮助和信息!上帝保佑先生! – 2015-01-21 08:26:38

0

4是总的休假时间..

对不起,我想弄个混乱..我需要得到总小时数......我试过了,如果休假时间范围将覆盖整个休息时间,我认为不会有冲突..如果只有部分休息时间将被覆盖,第一个条件将是虚假的。

如果员工的休息时间是上午11:00到下午12:00,那么他提交的休假是从上午11:30到2: 00Pm总假期应只返回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语句的首要条件。

相关问题