我们刚刚更改了我们的电话系统,现在每个代理都会以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
时间戳是在事实之后写的,因此时间戳为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行代替这一行....如果不是,那就太容易了!
提前谢谢你!
答案 0 :(得分:1)
试试这个。我在代码中评论过,但基本算法
希望这会有所帮助,这是一个有趣的挑战!
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]