来自CDR的同时通话

时间:2020-03-05 18:49:38  来源:igfitidea点击:

当每个事件只有开始时间和持续时间时,我需要对同时发生的事件进行分析。

细节

我有一个标准的CDR通话详细记录,其中包括:

  • 通话日期(每次通话开始的时间
  • 持续时间(整数,通话持续时间的秒数)
  • 频道(字符串)

我需要提出的是在给定的时间段内每秒进行某种同时调用的分析。例如,我们昨天有同时通话的图表。

(问题是相同的,如果我们在网站上保留了访问者的日志,并且持续时间很长,希望同时获得一组网页的客户)

算法是什么?

我可以遍历给定时间段内的记录,并填充一个数组,该数组的每个存储桶对应于整个时间段内的1秒。这可行并且似乎很快,但是如果时间周期很大(例如..1年),则需要大量内存(3600x24x365x4字节〜120MB aprox)。

这是用于基于Web的交互式应用程序,因此我的内存占用空间应该足够小。

编辑

同时,我的意思是所有呼叫都在给定的秒数上进行。第二个是我的最小单位。我不能使用更大的值(例如一个小时),因为一个小时内的所有通话都不必同时保持。

解决方案

回答

我会在数据库上实现这一点。在DATEPART中使用GROUP BY子句,我们可以获取想要的任何时间段的同时调用的列表,以秒,分钟,小时为单位。

在Web端,我们只需要显示查询返回的直方图。

回答

@ eric-z-beard:我真的很希望能够在数据库上实现这一点。我喜欢建议,尽管它似乎可以带来一些好处,但我不太完全理解。你能详细说明吗?请回想一下,每个呼叫将持续几秒钟,并且每一秒都需要计数。如果使用DATEPART(或者MySQL上类似的东西),那么GROUP BY应该使用秒。参见关于同时记录的说明。

对此进行详细说明,我找到了一种使用临时表解决此问题的方法。假设温度保持从tStart到tEnd的所有秒数,我可以

SELECT temp.second, count(call.id)
FROM call, temp
WHERE temp.second between (call.start and call.start + call.duration)
GROUP BY temp.second

然后,按照建议,Web应用程序应将其用作直方图。

回答

我们可以将静态Numbers表用于许多此类SQL技巧。 Numbers表仅包含0到n的整数,例如10000。

然后,临时表永远不需要创建,而是一个子查询,例如:

SELECT StartTime + Numbers.Number AS Second
FROM Numbers

回答

我们可以使用3个字段创建表"'simultaneous_calls'":

yyyymmdd  Char(8),
day_second Number,  -- second of the day,
count          Number   -- count of simultaneous calls

Web服务可以从此表中获取"计数"值并进行一些统计。

Simultaneous_calls表将由某些批处理程序填充,这些程序将在每天结束后每天启动。

假设我们使用Oracle,该批处理可能会启动执行以下操作的PL / SQL过程:

  • 在一天中的每一秒追加带有24 * 3600 = 86400条记录的表,默认的"计数"值= 0。
  • 定义查询的" day_cdrs"游标:
Select to_char(calldate, 'yyyymmdd')              yyyymmdd,
         (calldate - trunc(calldate)) * 24 * 3600   starting_second,
         duration                                              duration
From cdrs
Where cdrs.calldate >= Trunc(Sysdate -1)
    And cdrs.calldate 

Iterates the cursor to increment 'count' field for the seconds of the call:

For cdr in day_cdrs
Loop 
   Update simultaneos_calls
   Set      count = count + 1
   Where yyyymmdd = cdr.yyyymmdd
       And day_second Between cdr.starting_second And cdr.starting_second + cdr.duration;
End Loop;