计算从开始时间到结束时间的移位的SQL函数

计算从开始时间到结束时间的移位的SQL函数,sql,sql-server,Sql,Sql Server,我一直在尝试使用一个函数来计算员工从开始时间到结束时间的工作班次。这是到目前为止我所掌握的代码,似乎计算的移位是错误的 Shift 1 from 08:00:00 - 16:30:00 Shift 2 from 16:00:00 - 00:30:00 Shift 3 from 00:00:00 - 08:30:00 此外,工作时间最多的班次在班次之间获胜 谢谢, G `函数[dbo].[ShiftDifferential]( @开始时间(0), @结束时间(0) ) 返回整数 作为 开始 -

我一直在尝试使用一个函数来计算员工从开始时间到结束时间的工作班次。这是到目前为止我所掌握的代码,似乎计算的移位是错误的

Shift 1 from 08:00:00 - 16:30:00
Shift 2 from 16:00:00 - 00:30:00
Shift 3 from 00:00:00 - 08:30:00
此外,工作时间最多的班次在班次之间获胜

谢谢, G


`函数[dbo].[ShiftDifferential](
@开始时间(0),
@结束时间(0)
)
返回整数
作为
开始
--声明@StartTime时间(0)
--声明@EndTime时间(0)
--在这里声明返回变量
声明@Shift1StartTime(0)
声明@Shift2StartTime时间(0)
声明@Shift3StartTime时间(0)
声明@Shift1EndTime时间(0)
声明@Shift2EndTime时间(0)
声明@Shift3EndTime时间(0)
声明@HrsShift1十进制(18,2)
声明@HrsShift2十进制(18,2)
声明@HrsShift3十进制(18,2)
声明@ShiftDiff int
--设置@StartTime='09:00:00'
--设置@EndTime='13:00:00'
设置@Shift1StartTime='08:00:00'
设置@Shift2StartTime='16:00:00'
设置@Shift3StartTime='00:00:00'
设置@Shift1EndTime='16:30:00'
设置@Shift2EndTime='00:30:00'
设置@Shift3EndTime='08:30:00'
--选择DATEDIFF(HH、@Shift1StartTime、@EndTime)
--工作时间在3班和1班之间
如果DATEDIFF(HH,@Shift1StartTime,@StartTime)<0和(DATEDIFF(HH,@Shift1StartTime,@EndTime)<8.0和DATEDIFF(HH,@Shift1StartTime,@EndTime)>0)
开始
--打印“班次3-1步骤1”
设置@HrsShift3=DATEDIFF(HH、@StartTime、@Shift1StartTime)
设置@HrsShift1=DATEDIFF(HH、@Shift1StartTime、@Endtime)
--打印@HrsShift3
--打印@HRSShift 1
--上班时间最多
如果@hrsshift 3>则@hrsshift 1
开始
设置为@ShiftDiff=3
结束
其他的
开始
设置@ShiftDiff=1
结束
结束
--每小时轮班一次
if(DATEDIFF(HH,@Shift1StartTime,@StartTime)=0和DATEDIFF(HH,@Shift1StartTime,@EndTime)0和DATEDIFF(HH,@Shift1StartTime,@EndTime)0)
开始
--打印“班次1-2步骤1”
设置@HrsShift1=DATEDIFF(HH、@StartTime、@Shift2StartTime)
设置@HrsShift2=DATEDIFF(HH,@Shift2StartTime,@Endtime)
--打印@HRSShift 1
--打印@HRSShift 2
--用最多的时间换班
如果@hrsshift 1>则@hrsshift 2
开始
设置@ShiftDiff=1
结束
其他的
开始
设置@ShiftDiff=2
结束
结束
--每小时轮班2次
如果(DATEDIFF(HH,@Shift2StartTime,@StartTime)=0和DATEDIFF(HH,@Shift2StartTime,@EndTime)0和DATEDIFF(HH,@Shift2StartTime,@EndTime)@HrsShift3
开始
设置@ShiftDiff=2
结束
其他的
开始
设置为@ShiftDiff=3
结束
结束
--时间是三班

如果(DATEDIFF(HH,@Shift3StartTime,@StartTime)=0和DATEDIFF(HH,@Shift3StartTime,@EndTime)0和DATEDIFF(HH,@Shift3StartTime,@EndTime)感觉就像是在尝试对基于集合的问题采取迭代方法

在我看来,您似乎在试图找到与时间表条目中输入的时间重叠最多的班次

仔细研究一下,你会发现它非常基于集合,并且很容易扩展,因为如果你愿意的话,你可以使用时间表。这假设事情开始时使用
time
类型,但我将其转换为
datetime
,因为班次可能会在第二天结束

with 
Shifts as
(
SELECT ShiftID, cast(StartTime as datetime) as StartTime, 
    case 
      when EndTime < StartTime 
      then dateadd(day,1,cast(EndTime as datetime)) 
      else cast(EndTime as datetime) 
    end as EndTime
FROM Shifts
),
Times as 
(select 1 as TimeID,
    cast(@StartTime as datetime) as StartTime, 
    case 
      when @EndTime < @StartTime 
      then dateadd(day,1,cast(@EndTime as datetime)) 
      else cast(@EndTime as datetime) 
    end as EndTime
),
Overlaps as
(
select s.ShiftID, t.TimeID, 
       case when s.StartTime > t.StartTime then s.StartTime else t.StartTime end as StartOverlap,
       case when s.EndTime < t.EndTime then s.EndTime else t.EndTime end as EndOverlap,
from Shifts s
cross join Times t
),
OrderedOverlaps as
(
select *, row_number() over(partition by TimeID order by datediff(min,StartOverlap,EndOverlap) desc) as RowNum
from Overlaps
)
select s.ShiftID, t.TimeID
from OrderedOverlaps
where RowNum = 1;
与
转变为
(
选择ShiftID,cast(StartTime作为datetime)作为StartTime,
案例
当EndTimet.StartTime然后s.StartTime else t.StartTime结束为StartOverlap时,
当s.EndTime
你好,罗布,谢谢你的快速回复。我已经测试了一些案例,代码看起来不错。但是我在夜班上遇到了问题,例如,这应该是第三班,因为大多数工作时间都在第三班。`SET@StartTime='22:00:00'SET@EndTime='03:30:00'还有第一个select语句'FROM Shifts'是我的表ID和StartTime/EndTime信息?datediff(min,StartOverlap,EndOverlap)你的意思是datediff(mi,StartOverlap,EndOverlap)对吗?啊,是的。我实际上是指分钟。你是对的,应该有一些代码将“下一个日班”放进去。比如:union all选择ShiftID,dateadd(day,1,cast(StartTime作为datetime))作为StartTime,dateadd(天,1,当EndTimewith Shifts as ( SELECT ShiftID, cast(StartTime as datetime) as StartTime, case when EndTime < StartTime then dateadd(day,1,cast(EndTime as datetime)) else cast(EndTime as datetime) end as EndTime FROM Shifts ), Times as (select 1 as TimeID, cast(@StartTime as datetime) as StartTime, case when @EndTime < @StartTime then dateadd(day,1,cast(@EndTime as datetime)) else cast(@EndTime as datetime) end as EndTime ), Overlaps as ( select s.ShiftID, t.TimeID, case when s.StartTime > t.StartTime then s.StartTime else t.StartTime end as StartOverlap, case when s.EndTime < t.EndTime then s.EndTime else t.EndTime end as EndOverlap, from Shifts s cross join Times t ), OrderedOverlaps as ( select *, row_number() over(partition by TimeID order by datediff(min,StartOverlap,EndOverlap) desc) as RowNum from Overlaps ) select s.ShiftID, t.TimeID from OrderedOverlaps where RowNum = 1;