在SQL中拆分重叠时间

时间:2017-11-14 07:07:16

标签: sql sql-server sql-server-2016

我要求平均分割日期时间重叠的记录的持续时间。

实施例: Refer this picture for example

根据示例,如果我计算订单1的机器的总运行时间,则为3小时。但我希望它是2个小时,因为在同一台机器上,另一个订单在该持续时间之间运行(从上午9点到上午11点)。

我尝试搜索表单,并指出所有内容都排除重叠持续时间或执行其他功能。但我想分割所有记录的重叠持续时间。

样本表结构:

declare @st datetime, @et datetime;

DECLARE @table TABLE (Machine varchar(4),OrderId varchar(6),StartTime DateTime2, EndTime DateTime2)

INSERT INTO @table SELECT 'M2','ORD1','2017-11-01 10:30:00.000', '2017-11-01 12:00:00.000'
INSERT INTO @table SELECT 'M2','ORD2','2017-11-01 11:00:00.000', '2017-11-01 12:30:00.000'
INSERT INTO @table SELECT 'M2','ORD3','2017-11-01 11:30:00.000', '2017-11-01 13:00:00.000'

预期成果: Expected Result

基于上图,
ORD1的持续时间= 30分钟+ 15分钟(ORD1和ORD2之间重叠30分钟)+ 10分钟(ORD1,ORD2和ORD3之间重叠30分钟)
ORD2的持续时间= 15 MIN + 10 MIN + 15 MIN
ORD3的持续时间= 10分钟+ 15分钟+ 30分钟

机器总运行时间为55 + 40 + 55 = 150 MIN(2小时30分钟)

谢谢, Aravinth

2 个答案:

答案 0 :(得分:0)

您应该可以使用“窗口函数”来确定总体跨度,然后除以处理的订单数量,沿着这些行:

{{1}}

更多;我们需要你提供更多细节。

答案 1 :(得分:0)

感谢所有回复。最后,在我们的团队成员的帮助下,我们已经介绍了这种情况。以下是解决方案,

 DECLARE @table TABLE (OrdId varchar(12),MId varchar(4), ST DateTime, ET DateTime)

INSERT INTO @table SELECT '10001','M1','2017-11-01 10:30:00.000', '2017-11-01 12:00:00.000' INSERT INTO @table SELECT '10002','M1','2017-11-01 11:00:00.000', '2017-11-01 12:30:00.000' INSERT INTO @table SELECT '10003','M1','2017-11-01 11:30:00.000', '2017-11-01 14:00:00.000'  INSERT INTO @table SELECT '10004','M2','2017-11-01 14:30:00.000', '2017-11-01 16:00:00.000' 

DECLARE @ST datetime, @ET datetime, @NEXT_ST datetime, @RC smallint, @MCHr smallint; set @MCHr = 0; set @ST = (select MIN(ST) AS ST from @table where  MId = 'M1' and OrdId = '10001') set @ET = (select MAX(ET) AS ET from @table where  MId = 'M1' and OrdId = '10001') WHILE @ST < @ET  BEGIN
       set @NEXT_ST = (select MIN(ST) AS ST from @table where  MId = 'M1' and ST > @ST)
       if @NEXT_ST is not null
              begin
                     set @RC = ( SELECT count(*) from @table where MId = 'M1' and (@ST >= ST and @ST < @NEXT_ST))
                     if @RC > 0
                     begin
                           SET @MCHr  = @MCHr + (select DATEDIFF(MI,0,@NEXT_ST-@ST) / @RC);
                     end;
                     set @ST = @NEXT_ST;
              end;
       else
              begin
                     set @NEXT_ST = (select MIN(ET) AS ET from @table where  MId = 'M1' and (@ST >= ST and @ST < ET))
                     set @RC = ( SELECT count(*) from @table where MId = 'M1' and (@ST >= ST and @ST < ET))
                     if @RC > 0
                           SET @MCHr  = @MCHr + (select DATEDIFF(MI,0,@NEXT_ST-@ST) / @RC)
                     set @ST = @NEXT_ST;
              end; END; select @MCHr as MCHr