2016-12-16 25 views
0

我们只是改变了我们的电话系统,目前正通过15个分钟的间隔记录每一个代理商,我们需要每个事件1线总和间隔的可变量一起

表事件:

empid | code | timestamp | duration 
5111 | 5 | 09:45:00 | 45 
5222 | 2 | 09:58:00 | 120 
5111 | 5 | 10:00:00 | 900 
5111 | 5 | 10:15:00 | 900 
5111 | 5 | 10:15:30 | 30  
5222 | 5 | 11:00:00 | 8 
5222 | 5 | 11:00:05 | 5 

时间戳writen在事实之后,在9:45:00的时间戳,45的持续时间是从9:44:15开始的,因为时间间隔在9:45停止,它是在那时写的,但我需要9:44:15保存

结果应该给我

empid | code | timestamp | duration 
5111 | 5 | 09:44:15 | 1875 
5222 | 2 | 09:56:00 | 120 
5222 | 5 | 10:59:52 | 13 

问题是手机被锁定的最大延迟时间为2小时,正如你可以看到我的员工#5222他在两条线上花了13秒......我可以加入同一张桌子10次。 1,以避免当有地方前行的结束时间=新线

这是MSSQL 2008

Select e.empid 
      ,e.code 
      ,convert(time(0),DATEADD(ss,- e.Duration, e.timestamp)) 
      ,e.duration + isnull(e1.duration,0) + isnull(e2.duration,0) 

    from [event] e 
left join [event] e0 on 
convert(TIME(0),DATEADD(ss,- e.Duration, e.timestamp)) = e0.timestamp 
and 
e.empid = e0.empid 
and 
e.code = e0.code 

left join [event] e1 on 
convert(TIME(0),DATEADD(ss,- e1.Duration, e1.timestamp)) = e.timestamp 
and 
e.empid = e1.empid 
and 
e.code = e1.code 



left join [event] e2 on 
convert(TIME(0),DATEADD(ss,- e2.Duration, e2.timestamp)) = e1.timestamp 
and 
e2.empid = e1.empid 
and 
e2.code = e1.code 

--etc...... 

where isnull(e0.duration,'-10') = '-10' 

的开始时间这工作,但离最佳远远相同的代码...

我宁愿使用一个聚合函数,但我不知道如何编写它,因为除了上次时间戳与新的持续时间匹配之外,没有comon键 - 使用此表的持续时间!

重要的是要知道代理5111可以在同一天再次使用代码5,并且我将需要2行代码,如果不是这样会太简单!

谢谢你提前!

回答

1

试试这个。我评论的代码,但基本算法

  1. 发现rowswhich的延续,即存在一个用来匹配了一次 你减去的持续时间
  2. 减去发现“原件”,即每次通话开始的行在延续
  3. 各原稿,发现下一个原来那么我们可以确定的时间范围内去寻找延续
  4. 加入它一起和延续加总持续时间适合每个原始

希望这会有所帮助,这是一个有趣的挑战!


declare @data table 
(
    empid int, 
    code int, 
    [timestamp] time, 
    duration int 
); 

insert into @data values(5111,5,'09:45',45), 
(5222,2,'09:58',120), 
(5111,5,'10:00',900), 
(5111,5,'10:15',900), 
(5111,5,'10:15:30',30), 
(5222,5,'11:00',8), 
(5222,5,'11:00:05',5), 
-- added these rows to include the situation you describe where 5111 goes again on code 5: 
(5111,5,'13:00',45), 
(5111,5,'13:15',900), 
(5111,5,'13:15:25',25); 

-- find where a row is a continuation 
with continuations as (
    select a.empid, a.code, a.[timestamp] , a.duration 
    from @data a 
    inner join @data b on a.empid = b.empid 
     and a.code = b.code 
    where dateadd(ss, -a.duration, a.[timestamp]) = b.[timestamp] 
), 
-- find the "original" rows as the complement of continuations 
originals as 
(
    select d.empid, d.code, d.[timestamp], d.duration 
    from @data d 
    left outer join continuations c on d.empid = c.empid and d.code = c.code and d.timestamp = c.timestamp 
    where c.empid is null 
), 
-- to hand the situation where we have more than one call for same agent and code, 
-- find the next timestamp for each empid/code 
nextcall as (
    select a.*, a2.[timestamp] nex 
    from originals a 
    outer apply (
     select top 1 [timestamp] 
     from originals a2 
     where a2.[timestamp] > a.[timestamp] 
      and a.empid = a2.empid 
      and a.code = a2.code 
     order by a2.[timestamp] desc 
    ) a2 
) 
select o.empid, 
    o.code, 
    dateadd(ss, -o.duration, o.timestamp) as [timestamp], 
    o.duration + isnull(sum(c.duration),0) as duration 
from originals o 
left outer join nextcall n on o.empid = n.empid and o.code = n.code and o.[timestamp] = n.[timestamp] 
left outer join continuations c on o.empid = c.empid 
    and o.code = c.code 
    -- filter the continuations on the range of times based on finding the next one 
    and c.[timestamp] > o.[timestamp] 
    and (n.nex is null or c.[timestamp] < n.nex) 
group by o.empid, 
    o.code, 
    o.duration, 
    o.[timestamp] 
+0

你好感谢你,逻辑上似乎罚款我了解它如何可以工作,是的,它是一个有趣的挑战,但确实在SQL Server 2008中我得到这个错误:“铅”是无法识别的内置在函数名中。 !我很有信心,当我尝试它:(是否有另一种选择?是的,我们很便宜,不升级到SQL服务器2016年!grrrr –

+0

已更新为使用外部申请代替LEAD。我认为它现在应该在2008年 –

+0

你是一个天才!!!!我会尝试一个更大的规模,但它似乎是我想要的,结果看起来很棒的测试样品!真棒!!!!!!!!谢谢谢谢谢谢! –