Почему в результатах запроса 1С дублируются записи при соединении таблиц?

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

При разработке отчетов и обработок в 1С часто возникает ситуация, когда количество строк в результате запроса превышает ожидания. Давайте разберем, почему это происходит и как правильно связывать данные, чтобы избежать появления «лишних» дублей.

Разберем причину возникновения проблемы

Основная причина появления дублирующих записей заключается в специфике работы оператора ВНУТРЕННЕЕ СОЕДИНЕНИЕ (или INNER JOIN). Когда мы связываем две таблицы без четкого указания критериев выбора, СУБД выполняет так называемое декартово произведение.

Представим ситуацию: в табличной части Товары нашего документа РеализацияТоваровУслуг содержится две строки. В свою очередь, в справочнике КонтактнаяИнформация для одного контрагента может быть записано множество различных сведений: юридический адрес, фактический адрес, телефон, электронная почта и так далее. Если в запросе мы соединяем эти таблицы только по полю Ссылка, база данных для каждой строки товара найдет абсолютно все записи контактной информации, принадлежащие контрагенту. В итоге, если у контрагента 5 записей в контактной информации, для двух строк товаров мы получим 10 строк в итоговой выборке.

Способы решения проблемы

Чтобы избежать дублей и лишних пустых строк, необходимо придерживаться следующих правил при написании запросов.

1. Фильтрация контактной информации по виду или типу

Нельзя просто соединять таблицы «напрямую». Нужно обязательно ограничить выборку конкретным видом информации, который вас интересует (например, только телефон). Это можно сделать в условии ПО или в секции ГДЕ.

Рассмотрим правильный пример ограничения по типу информации:


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

2. Использование Левого соединения для сохранения данных

Если мы используем ВНУТРЕННЕЕ СОЕДИНЕНИЕ, то при отсутствии у контрагента телефона документ вообще не попадет в выборку. Чтобы видеть документ даже тогда, когда телефон не указан, следует использовать ЛЕВОЕ СОЕДИНЕНИЕ (LEFT JOIN). При таком подходе, если телефон не найден, поля контактной информации будут просто заполнены значениями NULL, но сам документ останется в списке.

Оптимизация кода запроса

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

Достаточно использовать простое обращение:

Неправильно: РеализацияТоваровУслугТовары.Ссылка.Контрагент.Ссылка

Правильно: РеализацияТоваровУслугТовары.Ссылка.Контрагент

Каждая лишняя точка в запросе — это потенциальное дополнительное соединение таблиц, которое замедляет выполнение вашего запроса. Помните, что грамотно составленный запрос — это не только корректный результат, но и высокая производительность системы 1С.

Итоги: как сделать правильно

  1. Всегда проверяйте, сколько строк в подчиненных таблицах (например, в КонтактнаяИнформация).
  2. Используйте отборы по Тип или Вид в секции ГДЕ или в условии ПО.
  3. Отдавайте предпочтение ЛЕВОЕ СОЕДИНЕНИЕ, если вы не хотите потерять основные данные при отсутствии уточняющей информации.
  4. Избегайте лишних точек при обращении через Ссылка.

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

← На главную