SQL Server:工人轮班,不包括休息时间

SQL Server:工人轮班,不包括休息时间,sql,sql-server,Sql,Sql Server,我只是在SQLServer中编写这个函数。它计算工人的工作分钟数,不包括休息时间 ALTER FUNCTION getMinutesWork ( @startT dateTime, @endT dateTime) AS BEGIN DECLARE @result int = DATEDIFF(mi, @startT, @endT) --time difference including break times SET @startT = CAST(@star

我只是在SQLServer中编写这个函数。它计算工人的工作分钟数,不包括休息时间

ALTER FUNCTION getMinutesWork
    ( @startT dateTime,
      @endT dateTime)
AS
BEGIN
    DECLARE @result int = DATEDIFF(mi, @startT, @endT)  --time difference including break times
    SET @startT = CAST(@startT AS TIME)
    SET @endT = CAST(@endT AS TIME)

    -- work schedule  
    DECLARE @t1 datetime = CAST('08:00:00' AS TIME),  --work
            @t2 datetime = CAST('10:00:00' AS TIME),  --break                   
            @t3 datetime = CAST('10:15:00' AS TIME),  --w
            @t4 datetime = CAST('12:40:00' AS TIME),  --b
            @t5 datetime = CAST('13:25:00' AS TIME),  --w
            @t6 datetime = CAST('16:30:00' AS TIME),  --b 
            @t7 datetime = CAST('16:45:00' AS TIME),  --w
            @t8 datetime = CAST('18:15:00' AS TIME);  --b

    --excluding break times
    IF ((@startT <= @t2 AND @endT >@t2) AND (@startT < @t3 AND @endT >= @t3))
       SET @result = @result - DATEDIFF(mi, @t2, @t3) 

    IF ((@startT <= @t4 AND @endT >@t4) AND (@startT < @t5 AND @endT >= @t5))
       SET @result = @result - DATEDIFF(mi, @t4, @t5)

    IF ((@startT <= @t6 AND @endT >@t6) AND (@startT < @t7 AND @endT >= @t7))
       SET @result = @result - DATEDIFF(mi, @t6, @t7)

    IF ((@startT > @t8) AND (@endT > @t1))
       SET @result = @result - DATEDIFF(mi, @t1, @startT)

    --excluding break times if worker starts on break time
    SET @result = (CASE 
                     WHEN (@startT < @t1) 
                       THEN @result - DATEDIFF(mi, @startT, @t1)
                     WHEN (@startT > @t2 AND @startT < @t3) 
                       THEN @result - DATEDIFF(mi, @startT, @t3)
                     WHEN (@startT > @t4 AND @startT < @t5) 
                       THEN @result - DATEDIFF(mi, @startT, @t5)
                     WHEN (@startT > @t6 AND @startT < @t7) 
                       THEN @result - DATEDIFF(mi, @startT, @t7)
                     WHEN (@startT > @t8) AND (@endT < @t1)
                       THEN 0
                     ELSE @result
                 END)

----------'2004-10-19 20:00:00','2004-10-18 10:00:00'------------
    --excluding break times if worker finish his work on break time
    SET @result = (
CASE 
    WHEN (@endT < @t1) 
        THEN 0
    WHEN (@endT >= @t2 AND @endT < @t3) 
        THEN @result - DATEDIFF(mi,@t2,@endT)
    WHEN (@endT >= @t4 AND @endT < @t5) 
        THEN @result - DATEDIFF(mi,@t4,@endT)
    WHEN (@endT >= @t6 AND @endT < @t7) 
        THEN @result - DATEDIFF(mi,@t6,@endT)
    WHEN (@endT > @t8)
        THEN @result - DATEDIFF(mi,@t8,@endT)
    ELSE @result
END )

-----------------------------------------------------------------------------------

IF @result <0
    SET @result = 0
-----------------------------------------------------------------------------------

RETURN @result
End

我如何解决这个问题?

你能检查一下这是否有效吗? 我认为这解决了逻辑问题

声明@startT DATETIME=Cast('19:00:00'为时间),
@endT DATETIME=Cast('11:00:00'为时间);
声明@result INT=Datediff(mi、@startT、@endT);
声明@t1 DATETIME=Cast('08:00:00'为时间),--工作
@t2 DATETIME=Cast('10:00:00'为时间),--中断
@t3日期时间=Cast('10:15:00'为时间),--w
@t4 DATETIME=Cast('12:40:00'为时间),--b
@t5 DATETIME=Cast('13:25:00'为时间),--w
@t6 DATETIME=Cast('16:30:00'为时间),--b
@t7 DATETIME=Cast('16:45:00'为时间),--w
@t8 DATETIME=Cast(时间为18:15:00)--B
如果Datediff(mi,@startT,Cast('18:00:00'作为时间))<0
--我假定雇员不能在六点以前来上夜班
开始
设置@result=@result+1440;
如果((@endT>=@t3))
SET@result=@result-Datediff(mi、@t2、@t3)
如果((@endT>=@t5))
SET@result=@result-Datediff(mi、@t4、@t5)
如果((@endT>=@t7))
SET@result=@result-Datediff(mi、@t6、@t7)
结束
其他的
开始
如果((@startT@t2)和(@startT<@t3和@endT>=@t3))
SET@result=@result-DATEDIFF(mi、@t2、@t3)
如果((@startT@t4)和(@startT<@t5和@endT>=@t5))
SET@result=@result-DATEDIFF(mi、@t4、@t5)
如果(@startT@t6)和(@startT<@t7和@endT>=@t7))
SET@result=@result-DATEDIFF(mi、@t6、@t7)
结束
选择@result
--选择右('0'+强制转换(@result/60)%60作为VARCHAR),2)+':'+

--右('0'+CAST(@result%60作为VARCHAR),2)
我编辑了if语句部分,它工作了:

--total work time if worker stay overnight including break times
IF ((@startT <= @t8) AND (@endT < @startT))
BEGIN
    SET @result = DATEDIFF(mi,@startT,'23:59:59') + DATEDIFF(mi,'00:00:01',@endT) +1
    SET @result = @result - DATEDIFF(mi,@t8,'23:59:59') - DATEDIFF(mi,'00:00:01',@t1)-1     
END

-----------------------------------------------------------------------------------
    --excluding break times

IF (((@startT > @t8) AND (@endT > @t1)))        
    SET @result = @result - DATEDIFF(mi,@startT,'23:59:59') - DATEDIFF(mi,'00:00:01',@t1)-1     
IF ((@startT <= @t2 AND @endT >= @t3)) OR ((@startT > @t8) AND (@endT >= @t3))
    SET @result = @result - DATEDIFF(mi,@t2,@t3) 
IF ((@startT <= @t4 AND @endT >= @t5)) OR ((@startT > @t8) AND (@endT >= @t5))
    SET @result = @result - DATEDIFF(mi,@t4,@t5)
IF ((@startT <= @t6 AND @endT >= @t7)) OR ((@startT > @t8) AND (@endT >= @t7))
    SET @result = @result - DATEDIFF(mi,@t6,@t7)
——如果工人过夜,包括休息时间,则总工作时间
如果((@startT@t8)和(@endT>@t1)))
SET@result=@result-DATEDIFF(mi,@startT,'23:59:59')-DATEDIFF(mi,'00:00:01',@t1)-1
如果((@startT=@t3))或(@startT>@t8)和(@endT>=@t3))
SET@result=@result-DATEDIFF(mi、@t2、@t3)
如果((@startT=@t5))或(@startT>@t8)和(@endT>=@t5))
SET@result=@result-DATEDIFF(mi、@t4、@t5)
如果((@startT=@t7))或(@startT>@t8)和(@endT>=@t7))
SET@result=@result-DATEDIFF(mi、@t6、@t7)

如果您也有日期部分,您将不会有任何问题。所有员工的休息时间完全相同,夜班工人在18:15到08:00之间没有休息时间?没有夜班。但是普通工人可以在20:00到10:00之间工作。如果是这样的话,函数应该返回2小时,它确实返回了。但是,如果工人在20:00到11:00之间工作,则不排除10:00-10:15的休息时间,这就是问题所在。如果班次是从
18:00
10:30
,那么结果应该是
2小时30分钟
?(18:00->18:15+08:00->10:00+10:15->10:30)。是的!这正是我想要做的,谢谢你,但我尝试了其他方法,效果很好:)
--total work time if worker stay overnight including break times
IF ((@startT <= @t8) AND (@endT < @startT))
BEGIN
    SET @result = DATEDIFF(mi,@startT,'23:59:59') + DATEDIFF(mi,'00:00:01',@endT) +1
    SET @result = @result - DATEDIFF(mi,@t8,'23:59:59') - DATEDIFF(mi,'00:00:01',@t1)-1     
END

-----------------------------------------------------------------------------------
    --excluding break times

IF (((@startT > @t8) AND (@endT > @t1)))        
    SET @result = @result - DATEDIFF(mi,@startT,'23:59:59') - DATEDIFF(mi,'00:00:01',@t1)-1     
IF ((@startT <= @t2 AND @endT >= @t3)) OR ((@startT > @t8) AND (@endT >= @t3))
    SET @result = @result - DATEDIFF(mi,@t2,@t3) 
IF ((@startT <= @t4 AND @endT >= @t5)) OR ((@startT > @t8) AND (@endT >= @t5))
    SET @result = @result - DATEDIFF(mi,@t4,@t5)
IF ((@startT <= @t6 AND @endT >= @t7)) OR ((@startT > @t8) AND (@endT >= @t7))
    SET @result = @result - DATEDIFF(mi,@t6,@t7)