Одновременные звонки из CDR

Мне нужно провести анализ одновременных событий, имея только время начала и продолжительность каждого события.

Подробности

У меня есть стандартная детальная запись вызова CDR, которая, среди прочего, содержит:

  • calldate (время начала каждого звонка
  • продолжительность (int, секунды продолжительности звонка)
  • канал (строка)

Что мне нужно придумать, так это своего рода анализ одновременных вызовов каждую секунду в течение заданного периода времени. Например, график одновременных звонков у нас был вчера.

(Проблема такая же, если у нас есть журналы посетителей с определенной продолжительностью на веб-сайте и мы хотим получить одновременных клиентов для группы веб-страниц)

Каков был бы ваш алгоритм?

Я могу перебирать записи за заданный период и заполнять массив, где каждый сегмент массива соответствует 1 секунде в общем периоде. Это работает и кажется быстрым, но если период времени большой (скажем, 1 год), мне понадобится много памяти (3600x24x365x4 байт ~ 120 МБ приблизительно).

Это для веб-интерактивного приложения, поэтому объем моей памяти должен быть достаточно небольшим.

Редактировать

Под одновременным я имею в виду все звонки в данную секунду. Второй будет моей минимальной единицей. Я не могу использовать что-то большее (например, час), потому что все звонки в течение часа не нужно удерживать одновременно.

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
0
3 236
4

Ответы 4

Я бы реализовал это в базе данных. Используя предложение 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, которая выполняет следующие действия:

  1. Добавляет таблицу с 24 * 3600 = 86400 записями для каждой секунды дня со значением 'count' по умолчанию = 0.
  2. Определяет курсор 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 
  1. Итерирует курсор для увеличения поля «счетчик» в секундах вызова:
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;

Другие вопросы по теме