При работе с регистрами сведений часто возникает задача объединения данных. Например, необходимо вывести информацию о состоянии физического лица за определенные периоды, где одинаковые состояния, идущие подряд, должны отображаться как один непрерывный интервал с датой начала и датой окончания. Простая СГРУППИРОВАТЬ здесь не поможет, так как она не учитывает хронологическую последовательность записей. Давайте разберем, как решить эту задачу с помощью механизмов языка запросов 1С.
Этот метод основан на нумерации записей внутри выборки. Присвоив каждой строке порядковый номер, мы можем соединить таблицу саму с собой по условию сдвига на одну позицию. Это позволяет определить момент, когда состояние прерывается или меняется.
Разберем реализацию по шагам:
АВТОНОМЕРЗАПИСИ.
ВЫБРАТЬ
Рег.ФизическоеЛицо КАК ФизическоеЛицо,
Рег.Состояние КАК Состояние,
Рег.Период КАК Период,
АВТОНОМЕРЗАПИСИ() КАК Номер
ПОМЕСТИТЬ Таб
ИЗ РегистрСведений.СостоянияФизическихЛиц КАК Рег
УПОРЯДОЧИТЬ ПО Рег.ФизическоеЛицо, Рег.Период;
ВЫБРАТЬ
Рег1.ФизическоеЛицо,
Рег1.Состояние,
Рег1.Период КАК Начало,
Рег2.Период КАК Окончание
ИЗ Таб КАК Рег1
ЛЕВОЕ СОЕДИНЕНИЕ Таб КАК Рег2
ПО Рег1.ФизическоеЛицо = Рег2.ФизическоеЛицо
И Рег1.Номер = Рег2.Номер - 1
УПОРЯДОЧИТЬ ПО Рег1.ФизическоеЛицо, Начало;
Таким образом, мы получаем пару Начало и Окончание для каждого интервала, что и является целью «схлопывания» записей.
Если задача требует более сложной обработки цепочек интервалов, используется метод «замыканий». Он эффективен, когда необходимо определить границы цепочек произвольной длины путем последовательного соединения таблицы с самой собой. Этот метод часто применяется при анализе графов или длинных последовательностей.
Суть подхода заключается в использовании нескольких временных таблиц:
// Пример логики итеративного сбора данных
ВЫБРАТЬ РАЗЛИЧНЫЕ
ПерваяДуга.НачалоДуги,
ВтораяДуга.КонецДуги,
ВтораяДуга.Ссылка
ПОМЕСТИТЬ Замыкания
ИЗ ЗамыканияДлины1 КАК ПерваяДуга
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЗамыканияДлины1 КАК ВтораяДуга
ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги;
При работе с такими сложными запросами важно учитывать производительность:
ПОМЕСТИТЬ. Это облегчает отладку и позволяет платформе 1С эффективнее работать с индексами.Период или конкретных ФизическихЛиц.ТаблицуЗначений и произвести обработку средствами встроенного языка 1С — это часто работает значительно быстрее, чем многоуровневые соединения в запросах.Анализируя задачу, всегда задавайтесь вопросом: действительно ли нужно «схлопывание» на уровне базы данных, или эту задачу можно решить на этапе формирования отчета или в модуле менеджера? В большинстве случаев предложенные выше методы в консоли запросов закрывают потребность в получении красивой итоговой таблицы.