Как правильно соединить две таблицы в запросе 1С, чтобы избежать дублирования строк?

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

При разработке отчетов или обработок в 1С часто возникает задача объединения данных из нескольких источников. Однако, при использовании стандартных соединений ЛЕВОЕ СОЕДИНЕНИЕ или ВНУТРЕННЕЕ СОЕДИНЕНИЕ, разработчики нередко сталкиваются с проблемой «размножения» строк. Это происходит, когда в подчиненной таблице для одной записи основной таблицы находится несколько совпадений. Давайте разберем, как грамотно решать такие задачи.

Вариант 1: Использование конструкции ВЫБОР КОГДА с агрегатной функцией СУММА

Это классический и наиболее надежный метод, который позволяет свернуть данные «на лету» внутри одного запроса. Суть заключается в том, что мы соединяем таблицы, а затем, с помощью СУММА(ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ 0 КОНЕЦ), распределяем показатели по нужным колонкам.

Рассмотрим пример кода, реализующего этот подход:


ВЫБРАТЬ 
    Т1.Код КАК Код, 
    СУММА(ВЫБОР КОГДА Т2.Статус = "В дороге" Тогда Т1.Количество Иначе 0 Конец) КАК КоличествоВДороге, 
    СУММА(ВЫБОР КОГДА Т2.Статус = "На складе" Тогда Т1.Количество Иначе 0 Конец) КАК КоличествоНаСкладе 
ИЗ Т1 КАК Т1 
ЛЕВОЕ СОЕДИНЕНИЕ Т2 КАК Т2 ПО (Т1.Код = Т2.Код) 
СГРУППИРОВАТЬ ПО Т1.Код

Почему это работает: Группировка по полю Код гарантирует, что количество строк в результате будет соответствовать количеству уникальных кодов в Т1. Конструкция ВЫБОР КОГДА позволяет нам логически разделить данные из Т2 по разным столбцам, сохраняя при этом целостность результата.

Вариант 2: Предварительная группировка во временные таблицы

Если объем данных велик или структура таблиц сложная, прямое соединение может привести к потере производительности или ошибкам из-за декартова произведения. В этом случае правильнее будет подготовить данные заранее с помощью временных таблиц ПОМЕСТИТЬ.

Разберем по шагам алгоритм оптимизации:

  1. Выгружаем основную таблицу в ВТ_Т1.
  2. Выполняем отбор для первой группы показателей и помещаем во временную таблицу (например, ПоСтатусуВДороге).
  3. Выполняем отбор для второй группы показателей и помещаем во вторую временную таблицу (например, ПоСтатусуНаСкладе).
  4. Соединяем подготовленные сгруппированные данные.

Пример реализации:


ВЫБРАТЬ Код, Количество ПОМЕСТИТЬ Т1 ИЗ Таблица1;

ВЫБРАТЬ Код, Количество КАК КоличествоВДороге 
ПОМЕСТИТЬ ПоСтатусуВДороге 
ИЗ Таблица2 
ГДЕ Статус = Значение(Перечисление.Статусы.ВДороге);

ВЫБРАТЬ Код, Количество КАК КоличествоНаСкладе 
ПОМЕСТИТЬ ПоСтатусуНаСкладе 
ИЗ Таблица2 
ГДЕ Статус = Значение(Перечисление.Статусы.НаСкладе);

ВЫБРАТЬ Т1.Код, Т1.Количество, Т2.КоличествоВДороге, Т3.КоличествоНаСкладе 
ИЗ Т1 
ЛЕВОЕ СОЕДИНЕНИЕ ПоСтатусуВДороге КАК Т2 ПО Т1.Код = Т2.Код 
ЛЕВОЕ СОЕДИНЕНИЕ ПоСтатусуНаСкладе КАК Т3 ПО Т1.Код = Т3.Код;

Анализ проблем при соединении

При выборе метода всегда задавайте себе вопрос: «Может ли быть несколько записей в Таблица2 для одного Кода?». Если ответ «Да», то прямое ЛЕВОЕ СОЕДИНЕНИЕ неизбежно приведет к дублям.

Основные рекомендации:

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

← На главную