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