При решении задач сбора метрик, телеметрии, логов операций или биржевых котировок разработчики часто сталкиваются с необходимостью сохранять данные с точностью до одной секунды. При этом для построения графиков и отчетов требуется быстро извлекать агрегированные показатели не только по стандартным периодам (минута, час, день), но и по произвольным квантам времени — например, по 5, 7, 30 или 500 секунд.
Разберем, какую структуру регистра целесообразно выбрать, с какими ограничениями платформы придется столкнуться и как составить запрос для группировки по произвольным временным интервалам.
Прежде чем выбирать объект конфигурации, проанализируем возможности виртуальных таблиц:
Секунда, Минута, Час, День, Неделя, Декада, Месяц, Квартал, Полугодие, Год, Регистратор, Период). Сгруппировать данные платформенным параметром с шагом в 7 или 500 секунд невозможно.ВЫРАЗИТЬ(... КАК ЧИСЛО) в языке запросов 1С выполняет банковское округление (к ближайшему четному числу). При прямом делении дат на интервалы границы временных отрезков могут смещаться, что требует математической корректировки.Рассмотрим два основных варианта проектирования структуры в зависимости от источника данных:
Вариант 1: Независимый непериодический регистр сведений (Рекомендуется)
Если данные поступают потоком (например, через внешние API, оборудование или обработку) и не привязаны к первичным документам системы, оптимально использовать независимый регистр сведений. Это исключает необходимость создавать фиктивные документы-регистраторы и значительно снижает накладные расходы на запись.
ПериодДанных (тип Дата, состав даты — Дата и время). Обязательно устанавливаем свойство «Индексировать».Продажи (тип Число), Покупки (тип Число).Вариант 2: Оборотный регистр накопления
Если фиксация данных неразрывно связана с проведением документов конфигурации, используем регистр накопления с видом «Обороты». Чтобы таблица итогов не разрасталась до критических размеров при посекундной записи, целесообразно отключить избыточную детализацию итогов по периодам.
Выясним, как сгруппировать записи по квантам произвольной длины (параметр &ИнтервалВСекундах) прямо в тексте запроса. Для этого приведем дату записи к количеству секунд относительно фиксированной точки отсчета, разделим на шаг интервала, приведем к целому и вернем обратно к типу даты.
Посмотрим на пример запроса к регистру сведений:
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(
ДАТАВРЕМЯ(2000, 1, 1),
СЕКУНДА,
ВЫРАЗИТЬ((РАЗНОСТЬДАТ(ДАТАВРЕМЯ(2000, 1, 1), Данные.ПериодДанных, СЕКУНДА) / &ИнтервалВСекундах) - 0.5 КАК ЧИСЛО(15, 0)) * &ИнтервалВСекундах
) КАК ИнтервалВремени,
СУММА(Данные.Продажи) КАК Продажи,
СУММА(Данные.Покупки) КАК Покупки
ИЗ
РегистрСведений.ДанныеОпераций КАК Данные
ГДЕ
Данные.ПериодДанных МЕЖДУ &ДатаНачала И &ДатаОкончания
СГРУППИРОВАТЬ ПО
ДОБАВИТЬКДАТЕ(
ДАТАВРЕМЯ(2000, 1, 1),
СЕКУНДА,
ВЫРАЗИТЬ((РАЗНОСТЬДАТ(ДАТАВРЕМЯ(2000, 1, 1), Данные.ПериодДанных, СЕКУНДА) / &ИнтервалВСекундах) - 0.5 КАК ЧИСЛО(15, 0)) * &ИнтервалВСекундах
)
АВТОУПОРЯДОЧИВАНИЕ
Разберем математическую логику выражения:
РАЗНОСТЬДАТ(ДАТАВРЕМЯ(2000, 1, 1), Данные.ПериодДанных, СЕКУНДА) вычисляет абсолютное смещение текущей даты в секундах от опорной точки 01.01.2000.&ИнтервалВСекундах определяет номер временного кванта. Смещение на - 0.5 перед вызовом ВЫРАЗИТЬ(... КАК ЧИСЛО(15, 0)) компенсирует банковское округление платформы 1С и реализует округление вниз (к началу интервала).&ИнтервалВСекундах и вызов функции ДОБАВИТЬКДАТЕ возвращают вычисленную метку начала кванта обратно в формат даты.В зависимости от объемов данных и сценариев работы можно применить дополнительные подходы:
СГРУППИРОВАТЬ ПО, а квантование меток времени выполнить в таблице значений на встроенном языке с помощью целочисленного деления или операции остатка от деления.