2017-10-16 50 views
2

我有一套机器使用记录,并有一个机器上使用多个工件,有时每个记录时间段重叠。现在我会得到实际的时间使用每个记录后删除重叠时间....但是,我很难作为一个SQL初学者....希望任何人都可以给我的帮助... thxSQL:如何得到正确的资源时间为每个时间记录后删除重叠

总计所用时间为CW0122小时EN01是小时ovelap时间

一部开拓创新TABLE

operid machine itemid   start_time     end_time    time_used 
    --------------------------------------------------------------------------------------------------  
    454  CW01  31  2017-10-16 08:30:00.000  2017-10-16 16:30:00.000   8 
    456  CW01  33  2017-10-16 13:30:00.000  2017-10-16 18:30:00.000   5 
    457  CW01  35  2017-10-16 21:30:00.000  2017-10-17 06:30:00.000   9 
    458  CW01  36  2017-10-16 15:30:00.000  2017-10-16 23:30:00.000   8 
    460  EN01  70  2017-10-16 08:30:00.000  2017-10-16 10:30:00.000   2 
    462  EN01  71  2017-10-16 09:30:00.000  2017-10-16 16:30:00.000   7 
去除之后

所需的表

operid machine itemid   start_time     end_time    time_used 
    --------------------------------------------------------------------------------------------------  
    454  CW01  31  2017-10-16 08:30:00.000  2017-10-16 16:30:00.000   6.33333 
    456  CW01  33  2017-10-16 13:30:00.000  2017-10-16 18:30:00.000   2.33333 
    457  CW01  35  2017-10-16 21:30:00.000  2017-10-17 06:30:00.000   8 
    458  CW01  36  2017-10-16 15:30:00.000  2017-10-16 23:30:00.000   5.33333 
    460  EN01  70  2017-10-16 08:30:00.000  2017-10-16 10:30:00.000   1.5 
    462  EN01  71  2017-10-16 09:30:00.000  2017-10-16 16:30:00.000   6.5 
+0

我建议做像C#的一些后端语言。在SQL Server中它不会有效。会有更好的表现,而且会更简单一些。 – Arkadiusz

+0

目前还不清楚如何获取请求的'time_used'值。其他人也有间隔,但他们仍然有正面的价值。 –

+0

我已经审查了删除重叠时间在SQL中的一些例子,但不完全是我想要的,不知道如果任何特殊的查询方法可以轻松地做到这一点...因为我总是看到来自这个网站的奇妙的查询语句...只是不知道他们是如何做到的:) –

回答

1
with Q(operid, machine, tm) as(
    -- split rows to time points (start(3), end(4), intersect time (1,2)) 
    select distinct A.operid,A.machine, 
      case N when 1 then (case when A.start_time>B.start_time 
           then A.start_time else B.start_time end) 
       when 2 then (case when A.end_time < B.end_time 
           then A.end_time else B.end_time end) 
       when 3 then A.start_time 
       else A.end_time 
      end 
    from TabD A 
    cross join (select 1 N union all select 2 union all select 3 union all select 4) N 
    left join TabD B 
     on B.machine=A.machine and B.operid!=A.operid 
     and B.start_time<A.end_time and B.end_time>A.start_time and N.N in(1,2) 
) 
select operid, machine, sum(time_len) 
    from (
    select X.operid, A.machine, s_tm, e_tm, 
      datediff(second, s_tm, e_tm)/3600.0/count(1) time_len 
    from (
     -- join time points to intervals 
     select operid, machine, tm e_tm, 
      lag(tm) over(partition by machine,operid order by tm) s_tm 
     from Q 
     where Q.tm is not null 
    ) X, 
     TabD A -- join source rows for interval of time for count it 
    where s_tm is not null 
     and A.start_time<X.e_tm and A.end_time>X.s_tm 
     and A.machine=X.machine 
    group by X.operid, A.machine, s_tm, e_tm 
) Y 
group by operid, machine 

例如在sqlfiddle.com

+0

哇...真棒!谢谢迈克!! ..... –

+0

检查。对不起,第一次使用这个平台。我感谢您的帮助! :) –