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