如何根据定义的表和数据检索当前班次记录,getdate()
以及哪个位于现有ShiftStartTime
和ShiftEndTime
根据定义的表和数据之间?
如果时间到了 12:00 AM 可以换班吗?
创建表 ShiftMaster ( ShiftID 字符(4), ShiftName 字符(7), ShiftDescripton varchar(20), ShiftStartTime 时间, ShiftEndTime 时间 )
插入到 ShiftMaster 价值观 ('SHF1', 'Shift A', 'First Shift', '07:15:01', '15:45:00'), ('SHF2', 'Shift B', '二班', '15:45:01', '00:15:00'), ('SHF3', 'Shift C', '三班', '00:15:01', '07:15:00')
SELECT * FROM VHASM2.ShiftMaster
WHERE FORMAT(getdate(),'HH:mm:ss') between ShiftStartTime and ShiftEndTime;
Run Code Online (Sandbox Code Playgroud)
select *
from ShiftMaster
where
'' + cast(datepart(hh, getdate()) as char(2)) + ':' + cast(datepart(n, getdate()) as char(2)) + ':' + cast(datepart(ss, getdate()) as char(2)) + '' >= ShiftStartTime
and
'' + cast(datepart(hh, getdate()) as char(2)) + ':' + cast(datepart(n, getdate()) as char(2)) + ':' + cast(datepart(ss, getdate()) as char(2)) + '' <= ShiftEndTime
Run Code Online (Sandbox Code Playgroud)
到目前为止的dbfiddle。
您可以将逻辑分为 3 部分:
查询:
-- time now
declare @tn as time = getdate() ;
select *
from ShiftMaster
where ShiftStartTime <= @tn and @tn < ShiftEndTime
or ShiftEndTime < ShiftStartTime and @tn < ShiftEndTime
or ShiftEndTime < ShiftStartTime and ShiftStartTime <= @tn
;
Run Code Online (Sandbox Code Playgroud)
在dbfiddle.uk 中测试。
另请注意,我使用了闭开区间和比较(避免邪恶的BETWEEN
*),因此该转变('00:15:00', '07:15:00')
代表之后00:15
和之前的任何时间07:15
(但不完全是 07:15)。因此,假设您正确定义了班次,那么每个时间点都应该在一个且只有一个班次中。
insert into ShiftMaster
values
('SHF1', 'Shift A', 'First Shift',
'07:15:00', '15:45:00'), -- notice the starts
('SHF2', 'Shift B', 'Second Shift',
'15:45:00', '00:15:00'), -- and the ends
('SHF3', 'Shift C', 'Third Shift',
'00:15:00', '07:15:00') ;
Run Code Online (Sandbox Code Playgroud)
使用您的方法,轮班之间会有 1 秒的间隔。
*:BETWEEN
在 Aaron Bertrand 的优秀博客文章中关于为什么要避免使用日期时间类型的更多信息和详细解释:和魔鬼有什么BETWEEN
共同点?.
您看到的问题是因为价值00:15:00
。我当前的时间21:43:26
大于00:15:00
,因此BETWEEN
检查失败。因为SQL Server无法知道它指的是第二天,午夜15点。
一种不优雅、不可重用的解决方法
IF NOT EXISTS
(
SELECT * FROM dbo.ShiftMaster
WHERE cast(convert(varchar, getdate(), 108)as time)
BETWEEN ShiftStartTime and ShiftEndTime)
BEGIN
SELECT * from ShiftMaster where ShiftID = 'SHF2';
END
ELSE
SELECT * FROM dbo.ShiftMaster
WHERE cast(convert(varchar, getdate(), 108)as time) BETWEEN ShiftStartTime and ShiftEndTime;
Run Code Online (Sandbox Code Playgroud)
结果
Run Code Online (Sandbox Code Playgroud)ShiftID ShiftName ShiftDescripiton ShiftStartTime ShiftEndTime SHF2 Shift B Second Shift 15:45:01.0000000 00:15:00.0000000
我会等待/寻找更优雅的解决方案
归档时间: |
|
查看次数: |
1534 次 |
最近记录: |