需要关于SQL递归查询的帮助

时间:2019-02-01 13:47:29

标签: tsql datetime recursive-query

我需要模拟生产订单的结束日期/时间。例如:生产订单需要4:55小时,但可能有1或2休息时间,也许1午餐时间取决于所需时间和当前时间。我需要计算当前时间和生产时间之间的所有休息时间。我只是不知道递归查询是否有用。

create table [TeamBreak]
(
  Team int ,
  StartBreak datetime,
  EndBreak datetime 
);

insert into [TeamBreak] values
(1, '1900-01-01 09:00', '1900-01-01 09:15'),
(1, '1900-01-01 12:00', '1900-01-01 12:30'),
(1, '1900-01-01 14:15', '1900-01-01 14:30'),
(2, '1900-01-01 18:15', '1900-01-01 18:30'),
(2, '1900-01-01 01:15', '1900-01-01 01:30')

DECLARE @start AS datetime='2019-01-31 7:00'
DECLARE @end AS datetime='2019-01-31 11:50' --prodction end date without break

SELECT SUM(iif(@end BETWEEN t.startbreak AND t.endbreak, DATEDIFF(n,t.startbreak,@end), DATEDIFF(n,t.startbreak,t.endbreak))) AS newtime
FROM teambreak AS t
WHERE CAST(t.startbreak AS time) 
    BETWEEN CAST(@start AS time) AND CAST(@end AS time) 
    OR CAST(t.endbreak AS time) BETWEEN CAST(@start as time) AND CAST(@end AS time)

顺便说一句,因为Access Front应用程序不支持时间类型,所以中断必须使用datetime类型而不是时间。

让我们开始到7h00am(不间断的第一个结束日期生产是11h55或4h55生产),在9 am-9h15am午餐时间12 pm-12:30pm休息。 结果应为40分钟(添加生产结束日期),而不是15分钟。

因此它将是7h00 + 4h55 = 11h55 + 15minutes(休息)= 12h10结束日期(但由于午餐时间而不可能),因此实际结束日期将是12:40 pm(因为12h-12:30已关闭) 。 的。我的第一个结果结束日期是12:10 pm,但是好的结果应该是12:40 pm

1 个答案:

答案 0 :(得分:0)

终于找到一种简单的方式与时间...不是resurcive CTE

首先,它在9:15-9:30发现休息时间。 它增加了15分钟到11:55。现在结束日期是12:10。 第二个循环它找到了午饭时间标准 它将30分钟增加到12:10。现在结束日期是我想要的12:40

declare @start as datetime='2019-01-31 07:00'    
declare @end as datetime='2019-01-31 11:55' --prudction end date without break1
declare @newEndDate as datetime    
declare @newAddTime as int=0    
declare @newAddTimeTotal as int=0
set @newEndDate=@end    
while( 1=1)    
begin    
    select @newAddTime=     
    coalesce(sum    
    (    
    case 
        when 
            CAST(@start AS TIME) between cast(t.startbreak  as time ) and     cast(t.endbreak as time) then datediff(n, CAST(@start AS TIME),cast(t.endbreak as time))
        else 
            datediff(n, CAST(t.startbreak AS TIME),cast(t.endbreak as time))
        end),0)
    ,@start=max(t.endbreak) 
    from teambreak t        
    where (cast(@start as time) <cast (t.endbreak as time)  and  cast(@end as time)>     cast(t.startbreak as time))        
    set @end =dateadd(n,@newAddTime,@end);
set  @newAddTimeTotal= @newAddTimeTotal+@newAddTime
    if @newAddTime=0
    break;
end

select @newAddTimeTotal,@end