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