Почему в запросе 1С возникает ошибка «Поле не входит в группу» и как её исправить?

Программист 1С v8.3 (Обычные формы) Управленческий учет IT и автоматизация бизнеса
← На главную

При модификации текстов запросов разработчики часто сталкиваются с ситуацией: достаточно убрать агрегатную функцию с числового поля (например, убрать СУММА), как платформа перестает выполнять запрос и выдает исключение вида «Поле не входит в группу...». Проанализируем, почему возникает такое поведение платформы и как правильно скорректировать запрос.

Выясним причину ошибки

В реляционных базах данных и встроенном языке запросов 1С действует строгое синтаксическое правило: если в запросе присутствует предложение СГРУППИРОВАТЬ ПО, то каждое поле из секции ВЫБРАТЬ обязано либо быть свернуто агрегатной функцией, либо присутствовать в списке группировки.

К агрегатным функциям в 1С относятся:

  1. СУММА — подсчет суммы числовых значений;
  2. КОЛИЧЕСТВО — подсчет количества записей (или различных записей);
  3. МАКСИМУМ — выбор максимального значения;
  4. МИНИМУМ — выбор минимального значения;
  5. СРЕДНЕЕ — расчет среднего арифметического.

Посмотрим на пример из подзапроса временной таблицы ВТТехОперации, где возникла ошибка:


ВЫБРАТЬ
    ОтчетПроизводстваЗаСменуТехнологическиеОперации.Ссылка,
    ОтчетПроизводстваЗаСменуТехнологическиеОперации.ТехнологическаяОперация,
    МИНИМУМ(ОтчетПроизводстваЗаСменуТехнологическиеОперации.Расценка) КАК Расценка,
    СУММА(ОтчетПроизводстваЗаСменуТехнологическиеОперации.Сумма) КАК Сумма,
    ЗначенияСвойствОбъектов.Значение,
    (ОтчетПроизводстваЗаСменуТехнологическиеОперации.Количество) КАК Количество
ПОМЕСТИТЬ ВТТехОперации
ИЗ
    Документ.ОтчетПроизводстваЗаСмену.ТехнологическиеОперации КАК ОтчетПроизводстваЗаСменуТехнологическиеОперации
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
    ПО ОтчетПроизводстваЗаСменуТехнологическиеОперации.Проект = ЗначенияСвойствОбъектов.Объект
СГРУППИРОВАТЬ ПО
    ОтчетПроизводстваЗаСменуТехнологическиеОперации.ТехнологическаяОперация,
    ОтчетПроизводстваЗаСменуТехнологическиеОперации.Ссылка,
    ЗначенияСвойствОбъектов.Значение
;

Как только с поля Количество была снята функция СУММА, СУБД больше не понимает, как именно сгруппировать строки: значений количества в документе по одной операции может быть несколько, а в секции СГРУППИРОВАТЬ ПО поле не объявлено. Система не может определить, какое именно значение подставить в объединенную строку, и генерирует ошибку выполнения.

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

Вариант 1. Добавление поля в секцию СГРУППИРОВАТЬ ПО

Если требуется вывести поле без агрегации, добавим его имя в список секции СГРУППИРОВАТЬ ПО. Разберем по шагам, как будет выглядеть фрагмент запроса:


ВЫБРАТЬ
    ОтчетПроизводстваЗаСменуТехнологическиеОперации.Ссылка,
    ОтчетПроизводстваЗаСменуТехнологическиеОперации.ТехнологическаяОперация,
    МИНИМУМ(ОтчетПроизводстваЗаСменуТехнологическиеОперации.Расценка) КАК Расценка,
    СУММА(ОтчетПроизводстваЗаСменуТехнологическиеОперации.Сумма) КАК Сумма,
    ЗначенияСвойствОбъектов.Значение,
    ОтчетПроизводстваЗаСменуТехнологическиеОперации.Количество КАК Количество
ПОМЕСТИТЬ ВТТехОперации
ИЗ
    Документ.ОтчетПроизводстваЗаСмену.ТехнологическиеОперации КАК ОтчетПроизводстваЗаСменуТехнологическиеОперации
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
    ПО ОтчетПроизводстваЗаСменуТехнологическиеОперации.Проект = ЗначенияСвойствОбъектов.Объект
СГРУППИРОВАТЬ ПО
    ОтчетПроизводстваЗаСменуТехнологическиеОперации.ТехнологическаяОперация,
    ОтчетПроизводстваЗаСменуТехнологическиеОперации.Ссылка,
    ЗначенияСвойствОбъектов.Значение,
    ОтчетПроизводстваЗаСменуТехнологическиеОперации.Количество
;

Важный нюанс: при добавлении числового показателя в группировку изменится детализация выборки. Если в документе есть две строки с одинаковой технологической операцией, но разным количеством (например, 5 и 10), они перестанут схлопываться в одну строку и попадут в результат раздельно.

Вариант 2. Замена СУММА на МАКСИМУМ или МИНИМУМ

Часто разработчики убирают СУММА, когда не хотят, чтобы числовое поле суммировалось (например, если количество дублируется из-за соединений таблиц или представляет собой фиксированную норму). В таком случае правильным решением будет замена СУММА на МАКСИМУМ или МИНИМУМ:


ВЫБРАТЬ
    ОтчетПроизводстваЗаСменуТехнологическиеОперации.Ссылка,
    ОтчетПроизводстваЗаСменуТехнологическиеОперации.ТехнологическаяОперация,
    МИНИМУМ(ОтчетПроизводстваЗаСменуТехнологическиеОперации.Расценка) КАК Расценка,
    СУММА(ОтчетПроизводстваЗаСменуТехнологическиеОперации.Сумма) КАК Сумма,
    ЗначенияСвойствОбъектов.Значение,
    МАКСИМУМ(ОтчетПроизводстваЗаСменуТехнологическиеОперации.Количество) КАК Количество
ПОМЕСТИТЬ ВТТехОперации
...

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

Вариант 3. Полное удаление группировки из подзапроса

Если задача состоит в получении точных детальных записей табличной части документа без объединения строк, следует отказаться от группировки в этой временной таблице полностью. Для этого удалим все агрегатные функции и само предложение СГРУППИРОВАТЬ ПО:


ВЫБРАТЬ
    ОтчетПроизводстваЗаСменуТехнологическиеОперации.Ссылка,
    ОтчетПроизводстваЗаСменуТехнологическиеОперации.ТехнологическаяОперация,
    ОтчетПроизводстваЗаСменуТехнологическиеОперации.Расценка КАК Расценка,
    ОтчетПроизводстваЗаСменуТехнологическиеОперации.Сумма КАК Сумма,
    ЗначенияСвойствОбъектов.Значение,
    ОтчетПроизводстваЗаСменуТехнологическиеОперации.Количество КАК Количество
ПОМЕСТИТЬ ВТТехОперации
ИЗ
    Документ.ОтчетПроизводстваЗаСмену.ТехнологическиеОперации КАК ОтчетПроизводстваЗаСменуТехнологическиеОперации
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
    ПО ОтчетПроизводстваЗаСменуТехнологическиеОперации.Проект = ЗначенияСвойствОбъектов.Объект
;

Если при этом требуется лишь исключить дублирование строк, возникшее при левом соединении с регистром сведений, вместо группировки используем конструкцию ВЫБРАТЬ РАЗЛИЧНЫЕ.

Рекомендации по структуре и оптимизации запроса

Рассмотрим дополнительные рекомендации, которые помогут повысить стабильность и быстродействие подобных пакетных запросов:

  1. Индексация временных таблиц: таблицы ВТПродукция, ВТРаспределение и ВТТехОперации в итоговом запросе связываются между собой по полям Ссылка и ТехнологическаяОперация. При создании временных таблиц рекомендуется добавлять конструкцию ИНДЕКСИРОВАТЬ ПО Ссылка, ТехнологическаяОперация, что существенно ускоряет операцию левого соединения в СУБД.
  2. Перенос условий по датам: условие ВТПродукция.Ссылка.Дата МЕЖДУ &Дата1 И &Дата2 наложено только в финальной выборке. Гораздо эффективнее перенести фильтрацию по дате документа непосредственно в секцию ГДЕ каждого исходного подзапроса пакета. Это предотвратит считывание лишних данных из базы в промежуточные временные таблицы.
  3. Использование конструктора запроса: при редактировании сложных текстов запросов всегда можно воспользоваться встроенным конструктором (через контекстное меню конфигуратора). Конструктор автоматически отслеживает поля выборки и корректно заполняет закладку «Группировка», предотвращая синтаксические ошибки.
← На главную