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