Мне нужно провести анализ одновременных событий, имея только время начала и продолжительность каждого события.
Подробности
У меня есть стандартная детальная запись вызова CDR, которая, среди прочего, содержит:
Что мне нужно придумать, так это своего рода анализ одновременных вызовов каждую секунду в течение заданного периода времени. Например, график одновременных звонков у нас был вчера.
(Проблема такая же, если у нас есть журналы посетителей с определенной продолжительностью на веб-сайте и мы хотим получить одновременных клиентов для группы веб-страниц)
Каков был бы ваш алгоритм?
Я могу перебирать записи за заданный период и заполнять массив, где каждый сегмент массива соответствует 1 секунде в общем периоде. Это работает и кажется быстрым, но если период времени большой (скажем, 1 год), мне понадобится много памяти (3600x24x365x4 байт ~ 120 МБ приблизительно).
Это для веб-интерактивного приложения, поэтому объем моей памяти должен быть достаточно небольшим.
Редактировать
Под одновременным я имею в виду все звонки в данную секунду. Второй будет моей минимальной единицей. Я не могу использовать что-то большее (например, час), потому что все звонки в течение часа не нужно удерживать одновременно.


Я бы реализовал это в базе данных. Используя предложение GROUP BY с DATEPART, вы можете получить список одновременных вызовов за любой желаемый период времени, по секундам, минутам, часам и т. д.
На веб-стороне вам нужно будет только отобразить гистограмму, возвращаемую запросом.
@ 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
Затем, как предлагается, веб-приложение должно использовать это как гистограмму.
Вы можете использовать статическую таблицу чисел для множества подобных SQL-трюков. Таблица чисел просто содержит целые числа от 0 до n для n, например 10000.
Тогда ваша временная таблица никогда не нуждается в создании, а вместо этого представляет собой подзапрос, например:
SELECT StartTime + Numbers.Number AS Second
FROM Numbers
Вы можете создать таблицу 'simultaneous_calls' с 3 полями:
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.
Таблица одновременных вызовов будет заполнена некоторой пакетной программой, которая будет запускаться каждый день после окончания дня.
Предполагая, что вы используете Oracle, пакет может запустить процедуру PL / SQL, которая выполняет следующие действия:
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
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;