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

Posted

技术标签:

【中文标题】需要关于 Sql 递归查询的帮助【英文标题】:Need Help on Sql recursive query 【发布时间】:2019-06-26 02:37:41 【问题描述】:

我需要模拟生产订单的结束日期/时间。例如:生产订单需要 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)

顺便说一句,break 必须是日期时间类型而不是时间,因为 Access 前端应用程序不支持时间类型。

让我们从早上 7 点开始(不休息的第一个结束日期生产是 11 点 55 分或 4 点 55 分),上午 9 点到 9 点 15 点午餐时间中午 12 点到 12 点 30 分休息。 结果应该是添加生产结束日期的 40 分钟,而不是 15 分钟。

所以它将是 7h00+4h55=11h55 + 15minutes(break)=12h10 enddate(但由于午餐时间不可能),所以真正的结束日期将是 12:40pm(因为 12h-12:30 已关闭) . 这。我的第一个结果结束日期是下午 12:10,但好的应该是下午 12:40

【问题讨论】:

您使用的是哪个 dbms? (该代码是特定于产品的。) 当您创建一个新问题并添加 SQL 标记时,会向您显示一个大建议,即您应该为您正在使用的特定 DBMS 添加一个标记,因为它们之间的功能和语法不同。请edit您的问题这样做。在您这样做之前,任何答案都是猜测,可能无法满足您的特定需求,这会浪费您和撰写答案的人的时间。如果您希望我们为您提供帮助,您需要提供必要的信息。 不清楚你的要求是什么 您的意思是要在2019-01-31 7:002019-01-31 11:50 之间找到以分钟为单位的休息时间吗? 【参考方案1】:

用了一阵子终于找到了一个简单的方法……不是复活的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

【讨论】:

以上是关于需要关于 Sql 递归查询的帮助的主要内容,如果未能解决你的问题,请参考以下文章

递归 PL SQL 查询帮助

SQL递归查询知多少

SQL Server CTE 递归查询全解

SQL递归查询知多少

sql server 递归查询

sql 怎么递归查询的方法: