首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按共享时间对事件进行分组

按共享时间对事件进行分组
EN

Stack Overflow用户
提问于 2013-12-09 14:57:11
回答 1查看 21关注 0票数 0

这里有一个很好的方法:假设您有一个包含开始和停止列的调用日志表,作为日期时间--大致如下所示:

代码语言:javascript
复制
callID, start, end, caller, callee
1, 12/9/13 7:01 am, 12/9/13 7:15 am,  555-1212, 222-1616
2, 12/9/13 7:04 am, 12/9/13 7:06 am,  555-1213, 222-1516
3, 12/9/13 7:04 am, 12/9/13 7:10 am,  555-1222, 222-1646
4, 12/9/13 7:07 am, 12/9/13 7:31 am,  555-1312, 222-1674
5, 12/9/13 7:08 am, 12/9/13 7:10 am,  555-1417, 222-1655

如何找到一天中并发调用的最大数量(重叠开始时间和结束时间的最高调用数)以及该集合的调用I?

试图找出比较多个持续时间的最佳策略。谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-09 15:16:19

这似乎起作用了。似乎有点复杂(我不喜欢做两次时间连接),但应该比较容易理解:

代码语言:javascript
复制
declare @t table (callID int not null,start datetime not null,[end] datetime not null,[caller] char(8) not null,callee char(8) not null)
insert into @t(callID, start, [end], [caller], callee) values
(1, '2013-09-12T07:01:00', '2013-09-12T07:15:00',  '555-1212', '222-1616'),
(2, '2013-09-12T07:04:00', '2013-09-12T07:06:00',  '555-1213', '222-1516'),
(3, '2013-09-12T07:04:00', '2013-09-12T07:10:00',  '555-1222', '222-1646'),
(4, '2013-09-12T07:07:00', '2013-09-12T07:31:00',  '555-1312', '222-1674'),
(5, '2013-09-12T07:08:00', '2013-09-12T07:10:00',  '555-1417', '222-1655')

;With Starts as (
    select Distinct start from @t
), Groups as (
    select s.start,COUNT(*) Cnt
    from Starts s inner join @t t on t.start <= s.start and t.[end] > s.start
    group by s.start
), Ordered as (
    select start,Cnt,RANK() OVER (ORDER BY Cnt desc) as rnk
    from Groups
), CallGroups as (
    select start,Cnt,ROW_NUMBER() OVER (ORDER BY start) as CallGroup
    from Ordered
    where rnk = 1
)
select CallGroup,t.*,cg.start
from CallGroups cg
    inner join
        @t t
            on
                t.start <= cg.start and t.[end] > cg.start

@t只是你的样本数据。Starts CTE查找所有的调用启动时间--从逻辑上讲,当一个或多个调用刚刚开始时,并发调用的最大数量是在某个点达到的。

然后,Groups会找到每个启动时间重叠的所有调用。然后,OrderedCallGroups找到达到最大值的时间(因为数据集中可能有多个最大值,我决定找到所有这样的最大值),并为每个maxima分配一个单独的CallGroup值。

最后,对于maxima,我们重新选择每个最大值都是活动的所有调用:

代码语言:javascript
复制
CallGroup            callID      start                   end                     caller   callee   start
-------------------- ----------- ----------------------- ----------------------- -------- -------- -----------------------
1                    1           2013-09-12 07:01:00.000 2013-09-12 07:15:00.000 555-1212 222-1616 2013-09-12 07:08:00.000
1                    3           2013-09-12 07:04:00.000 2013-09-12 07:10:00.000 555-1222 222-1646 2013-09-12 07:08:00.000
1                    4           2013-09-12 07:07:00.000 2013-09-12 07:31:00.000 555-1312 222-1674 2013-09-12 07:08:00.000
1                    5           2013-09-12 07:08:00.000 2013-09-12 07:10:00.000 555-1417 222-1655 2013-09-12 07:08:00.000

因此,样本数据的最大值(只有一个)发生在07:08,用于四个调用(如果希望包含计数,只需将cg.Cnt添加到最终查询中即可)。如果有另一个时间到达四个调用,我们将有8个输出行,第二组为4个,其中CallGroup 2。

意识到我可以消除一个CTE。而不是:

代码语言:javascript
复制
, Ordered as (
    select start,Cnt,RANK() OVER (ORDER BY Cnt desc) as rnk
    from Groups
), CallGroups as (
    select start,Cnt,ROW_NUMBER() OVER (ORDER BY start) as CallGroup
    from Ordered
    where rnk = 1
)
select CallGroup,t.*,cg.start
from CallGroups cg
    inner join
        @t t
            on
                t.start <= cg.start and t.[end] > cg.start

我们可以有:

代码语言:javascript
复制
, CallGroups as (
    select start,Cnt,RANK() OVER (ORDER BY Cnt desc) as rnk,
        ROW_NUMBER() OVER (PARTITION BY Cnt ORDER BY start) as CallGroup
    from Groups
)
select CallGroup,t.*,cg.start
from CallGroups cg
    inner join
        @t t
            on
                t.start <= cg.start and t.[end] > cg.start
where cg.rnk = 1

我一直误以为我们需要RANK()的结果,然后才能分配连续的CallGroup值,但事实并非如此。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20473639

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档