需要关于 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:00
和2019-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 递归查询的帮助的主要内容,如果未能解决你的问题,请参考以下文章