2016-09-26 58 views
1

我想比较时间与时间范围,如果该特定时间在于 - 在该时间范围内,则它应该返回记录。Sql Server - 仅比较24小时格式的时间?

例如,表“A”有:

+-----------+------+-------------+-----------+ 
| User_Code | Name | Shift_Start | Shift_End | 
+-----------+------+-------------+-----------+ 
|   1 | ABC | 04:01:00 | 11:00:00 | 
|   2 | DEF | 11:01:00 | 20:00:00 | 
|   3 | XYZ | 20:01:00 | 04:00:00 | 
+-----------+------+-------------+-----------+ 

现在我要检查其转变是它在这个特定日期时间:2016-09-26 02:51:59。 SQL查询应返回User_Code = 3Shift_StartShift_End的类型为time

我试图转换2016-09-26 02:51:59时间,然后shift_startshift_end使用between和使用logical operator,但我无法得到期望的结果与比较。

这让我感到莫名其妙。自从我尝试提出解决方案以来,已经过去了一个小时,但我无法这样做。试图用Google搜索,但没有得到任何东西。任何帮助将不胜感激。使用SQL Server从另一个角度2012

+1

如果你只想处理'TIME'而不是'DATETIME',它可能使您的生活更轻松分割您'20 :01:00 - 04:00:00 XYZ'分为两个范围:'00:00:00 - 04:00:00 XYZ'和'20:01:00 - 23:59:59 XYZ' – paul

+0

@paul,是的,但我并不想改变数据库结构,但我同意这会让事情变得更容易。 – NewbieProgrammer

回答

3

您需要更复杂的where条件,因为换档时间可以按任一顺序。

所以:

where ((shift_start < shift_end) and 
     cast(@datetime as time) between shift_start and shift_end) 
    ) or 
     ((shift_start > shift_end) and 
     cast(@datetime as time) not between shift_end and shift_start) 
    ) 
+0

谢谢兄弟。我没有意识到我可以做'不在'之间。 – NewbieProgrammer

+0

@戈登Linoff,我知道这是回答。但是当我尝试通过'@datetime ='2016-09-24 17:51:59''时,它给了2行(2和3),而不是一个。 – user3583912

+0

@ user3583912。 。 。 'between'和'not between'之间的运算符首先需要较低的值。 –

0

方法和搜索条件的日期部分添加到换挡开始时间和结束时间:

注意case语句,这种处理情况移位结束越过午夜。

DECLARE @dateTime DATETIME = '2016-09-26 02:51:59' 
-- Remove the time portion of above 
DECLARE @datePortion DATETIME = DATEADD(dd, 0, DATEDIFF(dd, 0, @dateTime)) 

SELECT * FROM TableA 
    WHERE @dateTime BETWEEN @datePortion + cast(Shift_Start as datetime) 
        AND CASE WHEN ShiftEnd < ShiftStart 
          THEN DATEADD(day, 1, @datePortion) 
          ELSE @datePortion 
         END + cast(Shift_End as datetime) 
+0

不幸的是,这并没有产生预期的结果。 – NewbieProgrammer

1
declare @t table(
    User_Code int, 
    Name varchar(20), 
    Shift_Start time, 
    Shift_End time 
    ); 
insert @t(User_Code,Name,Shift_Start,Shift_End) 
values 
(1,'ABC','04:01:00','11:00:00') 
,(2,'DEF','11:01:00','20:00:00') 
,(3,'XYZ','20:01:00','04:00:00'); 

尝试

declare @d datetime = '2016-09-26 02:51:59'; 

select * 
from @t 
cross apply (-- intermediate vars: rounded param 
     select dt = cast(cast(@d as date) as datetime) 
      ) r 
where @d between dateadd(d, case when Shift_Start<Shift_End then 0 else -1 end, dt) + cast(Shift_start as datetime) 
     and dt+cast(Shift_end as datetime);