<p>I need to come up with an analysis of simultaneus events, when having only starttime and duration of each event.</p>

<p><strong>Details</strong></p>

<p>I've a standard CDR call detail record, that contains among others:</p>

<ul>
<li>calldate (timedate of each call start</li>
<li>duration (int, seconds of call duration)</li>
<li>channel (a string)</li>
</ul>

<p>What I need to come up with is some sort of analysys of simultaneus calls on each second, for a given timedate period. For example, a graph of simultaneous calls we had yesterday.</p>

<p>(The problem is the same if we have visitors logs with duration on a website and wish to obtain simultaneous clients for a group of web-pages)</p>

<p>What would your algoritm be?</p>

<p>I can iterate over records in the given period, and fill an array, where each bucket of the array corresponds to 1 second in the overall period. This works and seems to be fast, but if the timeperiod is big (say..1 year), I would need lots of memory (3600x24x365x4 bytes ~ 120MB aprox).</p>

<p>This is for a web-based, interactive app, so my memory footprint should be small enough. </p>

<p><strong>Edit</strong></p>

<p>By simultaneous, I mean all calls on a given second. Second would be my minimum unit. I cannot use something bigger (hour for example) becuse all calls during an hour do not need to be held at the same time.</p>

[{'answer_id': 50614, 'author': 'Eric Z Beard', 'author_id': 1219, 'author_profile': 'https://Stackoverflow.com/users/1219', 'pm_score': 1, 'selected': False, 'text': '<p>I would implement this on the database.  Using a GROUP BY clause with DATEPART, you could get a list of simultaneous calls for whatever time period you wanted, by second, minute, hour, whatever.</p>\n\n<p>On the web side, you would only have to display the histogram that is returned by the query.</p>\n'}, {'answer_id': 53327, 'author': 'Pablo Alsina', 'author_id': 2295, 'author_profile': 'https://Stackoverflow.com/users/2295', 'pm_score': 0, 'selected': False, 'text': '<p>@eric-z-beard: I would really like to be able to implement this on the database. I like your proposal, and while it seems to lead to something, I dont quite fully understand it. Could you elaborate? Please recall that each call will span over several seconds, and each second need to count. If using DATEPART (or something like it on MySQL), what second should be used for the GROUP BY. See note on simultaneus.</p>\n\n<p>Elaborating over this, I found a way to solve it using a temporary table. Assuming temp holds all seconds from tStart to tEnd, I could do</p>\n\n<pre><code>SELECT temp.second, count(call.id)\nFROM call, temp\nWHERE temp.second between (call.start and call.start + call.duration)\nGROUP BY temp.second\n</code></pre>\n\n<p>Then, as suggested, the web app should use this as a histogram.</p>\n'}, {'answer_id': 169380, 'author': 'Cade Roux', 'author_id': 18255, 'author_profile': 'https://Stackoverflow.com/users/18255', 'pm_score': 0, 'selected': False, 'text': '<p>You can use a static Numbers table for lots of SQL tricks like this.  The Numbers table simply contains integers from 0 to n for n like 10000.</p>\n\n<p>Then your temp table never needs to be created, and instead is a subquery like:</p>\n\n<pre><code>SELECT StartTime + Numbers.Number AS Second\nFROM Numbers\n</code></pre>\n'}, {'answer_id': 170678, 'author': 'Aleksey Otrubennikov', 'author_id': 16209, 'author_profile': 'https://Stackoverflow.com/users/16209', 'pm_score': 0, 'selected': False, 'text': '<p>You can create table <code>\'simultaneous_calls\'</code> with 3 fields: <pre><code>yyyymmdd  Char(8),\nday_second Number,  -- second of the day,\ncount          Number   -- count of simultaneous calls</code></pre>\nYour web service can take \'count\' value from this table and make some statistics.</p>\n\n<p>Simultaneous_calls table will be filled by some batch program which will be started every day after end of the day. </p>\n\n<p>Assuming that you use Oracle, the batch may start a PL/SQL procedure which does the following:</p>\n\n<ol>\n<li>Appends table with 24 * 3600 = 86400 records for each second of the day, with default \'count\' value = 0.</li>\n<li>Defines the \'day_cdrs\' cursor for the query:</li>\n</ol>\n\n<pre><code>\nSelect to_char(calldate, \'yyyymmdd\')              yyyymmdd,\n         (calldate - trunc(calldate)) * 24 * 3600   starting_second,\n         duration                                              duration\nFrom cdrs\nWhere cdrs.calldate >= Trunc(Sysdate -1)\n    And cdrs.calldate </pre>\n\n<ol start="3">\n<li>Iterates the cursor to increment \'count\' field for the seconds of the call:</li>\n</ol>\n\n<pre>\nFor cdr in day_cdrs\nLoop \n   Update simultaneos_calls\n   Set      count = count + 1\n   Where yyyymmdd = cdr.yyyymmdd\n       And day_second Between cdr.starting_second And cdr.starting_second + cdr.duration;\nEnd Loop;\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/50576', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/2295/']