如何获得当前班次?

014*_*ser 6 sql-server

如何根据定义的表和数据检索当前班次记录,getdate()以及哪个位于现有ShiftStartTimeShiftEndTime根据定义的表和数据之间?

如果时间到了 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)

dbfiddle 和替代语句

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

ype*_*eᵀᴹ 7

您可以将逻辑分为 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共同点?.


Ran*_*gen 1

您看到的问题是因为价值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)

结果

ShiftID   ShiftName   ShiftDescripiton    ShiftStartTime      ShiftEndTime
SHF2      Shift B     Second Shift        15:45:01.0000000    00:15:00.0000000
Run Code Online (Sandbox Code Playgroud)

我会等待/寻找更优雅的解决方案