1

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

细节

我有一个标准的 CDR 呼叫详细记录,其中包含:

  • calldate(每次通话开始的时间日期
  • 持续时间(int,呼叫持续时间的秒数)
  • 频道(一个字符串)

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

(如果我们在网站上拥有具有持续时间的访问者日志并希望同时获得一组网页的客户,问题也是一样的)

你的算法是什么?

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

这是一个基于网络的交互式应用程序,所以我的内存占用应该足够小。

编辑

同时,我的意思是在给定的一秒内的所有呼叫。其次是我的最小单位。我不能使用更大的东西(例如小时),因为一个小时内的所有电话不需要同时保持。

4

4 回答 4

1

我会在数据库上实现这个。使用带有 DATEPART 的 GROUP BY 子句,您可以获取您想要的任何时间段的同时调用列表,按秒、分钟、小时等。

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

于 2008-09-08T20:40:09.997 回答
0

You can create table 'simultaneous_calls' with 3 fields:

yyyymmdd  Char(8),
day_second Number,  -- second of the day,
count          Number   -- count of simultaneous calls
Your web service can take 'count' value from this table and make some statistics.

Simultaneous_calls table will be filled by some batch program which will be started every day after end of the day.

Assuming that you use Oracle, the batch may start a PL/SQL procedure which does the following:

  1. Appends table with 24 * 3600 = 86400 records for each second of the day, with default 'count' value = 0.
  2. Defines the 'day_cdrs' cursor for the query:

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 
  1. 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;
于 2008-10-04T17:18:16.203 回答
0

@eric-z-beard:我真的很希望能够在数据库上实现这一点。我喜欢你的建议,虽然它似乎会导致一些事情,但我并不完全理解它。你能详细说明一下吗?请记住,每个呼叫将跨越几秒钟,并且每一秒都需要计数。如果使用 DATEPART(或 MySQL 上的类似功能),GROUP BY 应该使用几秒。见有关同步的注释。

详细说明了这一点,我找到了一种使用临时表来解决它的方法。假设 temp 保持从 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

然后,如建议的那样,网络应用程序应将其用作直方图。

于 2008-09-10T02:22:15.143 回答
0

您可以将静态 Numbers 表用于许多类似这样的 SQL 技巧。Numbers 表只包含从 0 到 n 的整数,例如 10000。

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

SELECT StartTime + Numbers.Number AS Second
FROM Numbers
于 2008-10-04T00:03:17.073 回答