在两个日期之间计数
Posted
技术标签:
【中文标题】在两个日期之间计数【英文标题】:Counting between two dates 【发布时间】:2012-10-13 01:24:04 【问题描述】:我写了一个程序,它需要 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..
这是我的问题:我需要同时发生的最大通话次数。换句话说,我需要通话高峰。任何建议或线索对我来说都会非常有用。
在这个时间范围内发生了 6 个调用,但其中 4 个是同时发生的,我想计算一下。最大点显示最大呼叫峰值。在此时间范围内发生了第 5 次和第 6 次调用,但对最大调用峰值没有影响。
【问题讨论】:
答案草图 - 将问题分成两部分。对于第一部分,您想计算出任何有趣时间的同时通话数量 - 在这种情况下,有趣的时间是通话开始时(因为通话数量刚刚增加)。对于每个有趣的时间,计算出当时的活跃呼叫数。 然后,对于每个间隔,计算出该时间段内该值的最大值(还包括该时间段开始之前或之后的最新值)。 【参考方案1】:这应该是一个 O(n log n) 算法:
-
将所有记录转储到#temp 表中
将时间范围一分为二,运行查询查看哪个时间范围的调用次数较多
修剪掉在另一半的记录
如果两半的调用次数相同,则保留并处理两半。这可能会导致您的工作集从 2 个增加到 4 个等,但对于不能产生与其他数量相同的任何“一半”,可能会再次下降
如果两半包含相同的记录:此分支可以标记为已完成。该呼叫在整个时间范围内是同时进行的。您可以在此处停止(标记为已确定)以获取“一个答案”或继续查找“所有答案”。
可以处理此问题的 SP 的草稿结构:
表格:#WorkingSets
分区(int):最初是左/右,然后是 LLL/LLR/RLR 等 session_id : 这可以同时出现在多个分区中 session_start 会话_结束 curr_range_start curr_range_end : 将开始/结束之间的范围减半 最终确定(位)变量
@max_calls_per_partition :一旦发现任何“最终确定的”集合就被锁定【讨论】:
【参考方案2】:我为执行类似查询所做的是使用数字辅助表(例如,数字为 1 到 100 万的表)。
像拼图一样查看查询。首先,假设您有开始和结束时间。
下午 12:00 - 下午 2:00
将它交叉加入数字表,现在你有
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 交叉应用(从您的表 t2 中选择 sum(1) numcalls,其中 t1.calculatedtimeinterval 在 t2.startdatetime 和 t2.enddatetime 之间)t3
赢了!
【讨论】:
以上是关于在两个日期之间计数的主要内容,如果未能解决你的问题,请参考以下文章