Нужна ли группировка в запросе к виртуальной таблице остатков регистра накопления?

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

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

Механизм неявной свертки в виртуальных таблицах

Рассмотрим базовый принцип работы виртуальной таблицы Остатки. Главная особенность этой таблицы заключается в том, что она не существует в базе данных физически. Когда мы обращаемся к ней в запросе, платформа 1С «на лету» формирует сложный SQL-запрос к физическим таблицам итогов и движений.

Важно понимать: виртуальная таблица гарантирует уникальность записей по набору выбранных измерений. Это означает, что если мы выбираем в запросе только измерения и ресурсы, платформа автоматически выполняет свертку данных. Проанализируем простой пример запроса:


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

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

Работа с реквизитами измерений «через точку»

Часто возникает сомнение: а что, если мы выбираем не само измерение, а его реквизит? Например, артикул номенклатуры. Изменится ли количество строк в результате запроса без группировки? Проанализируем следующую ситуацию:


ВЫБРАТЬ
    ТоварыНаСкладахОстатки.Номенклатура.Артикул КАК Артикул,
    ТоварыНаСкладахОстатки.В НаличииОстаток КАК Остаток
ИЗ
    РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки

Выясним, как платформа обрабатывает такие обращения. Сначала 1С получает уникальный набор данных из виртуальной таблицы (сворачивает остатки по ссылке Номенклатура). Только после получения этого свернутого набора выполняется LEFT JOIN к таблице справочника Номенклатура для получения артикула. Поскольку связь между ссылкой и её реквизитом всегда «один к одному», количество строк в результате запроса не увеличится. Таким образом, группировка по реквизитам измерений в виртуальной таблице остатков также не требуется.

Влияние на секцию ИТОГИ

Разберем еще одно частое заблуждение: необходимость группировки для корректной работы итогов. Посмотрим на пример кода:


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

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

Когда группировка в ВТ Остатков действительно необходима?

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

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

Почему возникают сомнения («эффект осадочка»)?

Проанализируем ситуацию, когда разработчики сталкиваются с «неверными» данными в остатках и начинают добавлять группировки. Как правило, корень проблемы кроется не в тексте запроса, а в целостности итогов базы данных.

В 1С существуют физические таблицы итогов, которые хранят рассчитанные данные на начало каждого месяца. Если в базе произошел программный сбой или некорректное прямое изменение данных в SQL, итоги могут «разойтись» с фактическими записями в таблице движений. В этом случае запрос к виртуальной таблице вернет неверный результат. Решением здесь является не добавление СГРУППИРОВАТЬ ПО, а выполнение процедуры «Пересчет итогов» в конфигураторе (или через стандартную обработку управления итогами).

Подведем итоги

При работе с виртуальной таблицей Остатки в 1С 8.3 следует придерживаться следующих правил:

Соблюдение этих простых принципов поможет вам писать оптимальные и читаемые запросы, соответствующие стандартам разработки 1С.

← На главную