在两个日期之间计数

时间:2012-10-23 06:46:59

标签: sql-server tsql datetime stored-procedures date-range

我编写了一个程序,它包含3个参数StartDate,EndDate和TimeRange。根据TimeRange,我的程序分开日期并单独计算它们。这是我的程序:

PROCEDURE [dbo].[Procedure1] 

    @Start datetime, 
    @Finish datetime,
    @TimeRange time
AS
BEGIN

    SET NOCOUNT ON;

    declare @TimeRanges as TABLE (SessionStart datetime, SessionEnd datetime);

     with TimeRanges as (
  select @Start as StartTime, @Start + @TimeRange as EndTime
  union all
  select StartTime + @TimeRange, EndTime + @TimeRange
    from TimeRanges
    where EndTime  < @Finish )
  select StartTime, EndTime, Count( Test.ScenarioID ) as TotalInboundArrivals
    from TimeRanges as TR left outer join
      dbo.Test as Test on TR.StartTime <= Test.SessionStartTime and Test.SessionCloseTime < TR.EndTime
    where Test.ScenarioID = 24  
    group by TR.StartTime, TR.EndTime   
END

例如,

Start Time: 11:00
End Time: 12:00
TimeRange : 05:00

This procudure splits them like
     TimeRange    TotalCallPeaks
    11:00 11:05      12
    11:05 11:10      8
    11:10 11:15      15 
    etc..

这是我的问题:我需要同时发生的最大呼叫。换句话说,我需要调用峰值。任何建议或线索对我来说都是如此有用。

enter image description here 在这个时间范围内发生了6次呼叫,但其中4次是在我想要计算的同时发生的。最大点显示最大调用峰值。在此时间范围内发生了第5次和第6次呼叫,但对最大呼叫峰值没有影响。

2 个答案:

答案 0 :(得分:0)

这应该是一个O(n log n)算法:

  1. 将所有记录转储到#temp表
  2. 将时间范围拆分为两个,运行查询以查看哪个时间范围有更多呼叫
    • 修剪另一半的记录
    • 如果两半的呼叫数相同,则
    • 保持并处理两半。这可能会导致你的工作集从2增加到4等,但是对于任何不能产生与其他人相同数量的“一半”,可能会再次下降
    • 如果两个半部分包含相同的记录:此分支可以标记为已完成。呼叫在整个时间范围内同时发生。您可以在此处(标记为已完成)停止“一个答案”或继续查找“所有答案”。
  3. 可以处理此问题的SP草案结构:

    表:#WorkingSets

    • 分区(int):最初左/右,然后是LLL / LLR / RLR等
    • session_id:这可以同时出现在多个分区中
    • 在session_start
    • session_ end
    • curr_range_start
    • curr_range_end:将开始/结束之间的范围减半。
    • 最终确定(位)

    <强>变量

    • @max_calls_per_partition:找到任何“已完成的”设置后锁定

答案 1 :(得分:0)

我执行类似查询所做的是使用辅助数字表(例如,数字为1到1百万的表)。

查看类似拼图的查询。首先,说你有你的开始和结束时间。

12:00 pm-2:00pm

交叉加入数字表,现在你已经

1; 12:00pm; 2:00pm
2; 12:00pm; 2:00pm
3; 12:00pm; 2:00pm
4; 12:00pm; 2:00pm
etc...

接下来,将辅助数字乘以您想要的间隔,例如10,例如

10; 12:00pm; 2:00pm
20; 12:00pm; 2:00pm
30; 12:00pm; 2:00pm
40; 12:00pm; 2:00pm
etc...

接下来,将计算出的数字添加到开始时间(如果这是您的间隔单位,则以分钟为单位)使用DATEADD函数

10; 12:00pm; 2:00pm; 12:10
20; 12:00pm; 2:00pm; 12:20
30; 12:00pm; 2:00pm; 12:30
40; 12:00pm; 2:00pm; 12:40
etc...

现在只抓取开始时间和结束时间之间的计算时间间隔,或者使用where子句,或者选择内部连接的范围,交叉应用等...

然后,说't1'现在是上面结果集中的派生表。对于每一行,选择在该时间点处于活动状态的呼叫数,如下所示:

选择* FROM t1 交叉应用(从yourtable t2中选择sum(1)numcalls,t2.startdatetime和t2.enddatetime之间的t1.calculatedtimeinterval)t3

赢!

相关问题