我想将时间与时间范围进行比较,如果该特定时间与该时间范围有关,那么它应该返回一条记录。
例如,表' 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 = 3
。 Shift_Start
和Shift_End
的类型为time
。
我已尝试将2016-09-26 02:51:59
转换为时间,然后使用shift_start
并使用shift_end
与between
和logical operator
进行比较,但我无法获得所需结果
这令我感到困惑。自从我尝试提出解决方案以来已经过了一个小时,但我无法这样做。尝试使用谷歌搜索,但也没有得到任何东西。任何帮助将不胜感激。使用SQL Server 2012。
答案 0 :(得分: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)
)
答案 1 :(得分: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);
答案 2 :(得分: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)