К статье
Практический материал

Разработка и Конфигурация · 10 мин

Левое соединение в 1С: что входит в результат соединения

Левое соединение в запросах 1С: что входит в результат, синтаксис, отличия от внутреннего соединения, типичные ошибки и примеры проверки результата.

Левое соединение в языке запросов 1С означает, что в результат попадут все записи левой таблицы — независимо от того, нашлось ли им соответствие в правой таблице. Для строк левой таблицы, которым не нашлось пары справа, поля правой таблицы будут заполнены значением NULL. Именно это отличает левое соединение от внутреннего, где в выборку попадают только совпавшие пары.

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

Конструкция записывается так: ЛЕВОЕ СОЕДИНЕНИЕ ПраваяТаблица КАК Псевдоним ПО УсловиеСвязи. Левой считается таблица, указанная в предложении ИЗ, правой — таблица после ключевых слов ЛЕВОЕ СОЕДИНЕНИЕ. Порядок таблиц имеет решающее значение: поменяйте их местами — и смысл запроса изменится на противоположный.

Что именно попадает в результат левого соединения

Результат левого соединения складывается из двух частей. Первая — строки, для которых условие связи выполнилось: они объединяются с соответствующими строками правой таблицы, как при обычном внутреннем соединении. Вторая — строки левой таблицы без пары: они попадают в результат «в одиночку», а все поля, взятые из правой таблицы, получают значение NULL.

Важно понимать, что количество строк в результате может оказаться больше, чем в левой таблице. Если одной записи слева соответствует несколько записей справа, левая строка продублируется столько раз, сколько нашлось совпадений. Это частая причина «задвоения» сумм в отчетах: соединили справочник товаров с таблицей партий — и каждый товар умножился на число партий.

Синтаксис и минимальный пример

Типовой пример — вывести всех контрагентов и их заказы, включая контрагентов без заказов:

ВЫБРАТЬ

Контрагенты.Ссылка КАК Контрагент,

Заказы.СуммаДокумента КАК СуммаЗаказа

ИЗ

Справочник.Контрагенты КАК Контрагенты

ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказПокупателя КАК Заказы

ПО Контрагенты.Ссылка = Заказы.Контрагент

Здесь левая таблица — справочник контрагентов, поэтому в выборку попадут все контрагенты. У тех, кто не делал заказов, поле СуммаЗаказа будет равно NULL. Если бы использовалось внутреннее соединение (ВНУТРЕННЕЕ СОЕДИНЕНИЕ), такие контрагенты просто исчезли бы из результата.

Условие связи после ПО может включать несколько выражений через И, сравнение с константой и проверку на диапазон. Однако условие «ИЛИ» в соединении резко замедляет запрос и часто приводит к декартову произведению — его стоит избегать.

Чем левое соединение отличается от внутреннего и правого

Выбор типа соединения определяет, какие строки сохранятся при отсутствии совпадений. Сравнение основных вариантов:

Тип соединенияЧто попадает в результатТиповой сценарий
ЛевоеВсе строки левой таблицы + совпадения справа, несовпавшие поля = NULLВсе товары, включая без остатков
ВнутреннееТолько строки, где есть совпадение в обеих таблицахТолько товары с ненулевыми остатками
ПравоеВсе строки правой таблицы + совпадения слеваРедко; обычно заменяют левым с перестановкой таблиц
ПолноеВсе строки обеих таблиц, NULL с несовпавшей стороныСверка двух наборов данных на расхождения

Когда какое соединение выбрать

Левое соединение

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

Внутреннее соединение

Нужны только пары с данными с обеих сторон; лишние строки и NULL недопустимы

Полное соединение

Нужно найти расхождения в обе стороны: что есть слева без пары и что есть справа без пары

Работа с NULL в полях правой таблицы

Значение NULL — не ноль и не пустая строка, а отсутствие значения. Любая арифметическая операция с NULL дает NULL, поэтому суммирование полей правой таблицы без обработки вернет NULL вместо ожидаемого нуля. Для подстановки значения по умолчанию используется функция ЕСТЬNULL:

ВЫБРАТЬ

Товары.Ссылка КАК Номенклатура,

ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток

ИЗ

Справочник.Номенклатура КАК Товары

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

ПО Товары.Ссылка = Остатки.Номенклатура

Проверка на NULL в условиях выполняется оператором ЕСТЬ NULL, а не сравнением через «=». Конструкция ГДЕ Остатки.Номенклатура ЕСТЬ NULL отберет именно те товары, по которым остатков нет — это стандартный прием поиска «отсутствующих» данных.

Типичные сценарии применения

Отчет по справочнику с необязательными движениями

Классическая задача — показать весь справочник (сотрудников, товаров, договоры) с данными регистра, где движения могут отсутствовать. Левое соединение от справочника к виртуальной таблице регистра гарантирует, что ни один элемент не потеряется. Дополнительно условие ЕСТЬ NULL позволяет выделить элементы без движений в отдельную группу отчета.

Поиск записей без пары

Обратная задача — найти «осиротевшие» данные: товары, которым не сопоставлена номенклатура поставщика, сотрудники без назначенного графика. Здесь левое соединение комбинируется с отбором ГДЕ ПраваяТаблица.Поле ЕСТЬ NULL — в результат попадут только несопоставленные записи.

Соединение с виртуальными таблицами регистров

При соединении с виртуальной таблицей остатков или оборотов параметры виртуальной таблицы (период, отбор) задавайте в её скобках, а не в секции ГДЕ основного запроса. Если вынести условие по полю правой таблицы в ГДЕ, оно отфильтрует строки с NULL — и левое соединение фактически превратится во внутреннее.

Как проверить, что соединение работает правильно

Надежный способ проверки — сравнить количество строк результата с количеством записей левой таблицы. Если строк меньше — часть данных потеряна (возможно, случайно применено внутреннее соединение или фильтр по полю правой таблицы). Если строк заметно больше — в правой таблице есть дубли по ключу связи, и суммы в отчете будут завышены.

Практический прием: выполните запрос в консоли запросов и отдельно посчитайте записи с Поле ЕСТЬ NULL. Это покажет, сколько элементов левой таблицы не имеет пары, и поможет оценить полноту данных правой таблицы.

Контрольные точки

Как проверить результат

Число строк результата
Норма

Не меньше числа записей левой таблицы (с учетом отборов)

Тревожный признак

Строк меньше — данные левой таблицы потеряны

Поля правой таблицы
Норма

NULL встречается только у записей без пары и обработан через ЕСТЬNULL

Тревожный признак

NULL попадает в итоги и арифметику без обработки

Суммы по соединенным полям
Норма

Совпадают с суммой по правой таблице в отдельном запросе

Тревожный признак

Суммы завышены — в правой таблице дубли по ключу связи

Типичные ошибки при использовании левого соединения

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

Типичные ошибки
01
Отбор по полю правой таблицы в секции ГДЕ — отсекает NULL-строки и превращает левое соединение во внутреннее
02
Отсутствие ЕСТЬNULL — в итогах и вычисляемых полях появляется NULL вместо нуля
03
Соединение по неуникальному ключу — строки левой таблицы дублируются, суммы задваиваются
04
Перепутан порядок таблиц — в результат попадают записи правой таблицы вместо левой
05
Сравнение поля с NULL через равенство — условие никогда не выполняется, нужен оператор ЕСТЬ NULL

Порядок безопасной разработки запроса

Порядок действий
  1. 1
    Определите главную таблицу — ту, все записи которой должны попасть в результат, и поставьте её в предложение ИЗ
  2. 2
    Подключите зависимую таблицу через ЛЕВОЕ СОЕДИНЕНИЕ с условием связи по уникальному ключу
  3. 3
    Все отборы по полям правой таблицы перенесите в условие ПО или в параметры виртуальной таблицы
  4. 4
    Оберните вычисляемые поля правой таблицы в ЕСТЬNULL(Поле, 0)
  5. 5
    Выполните запрос в консоли и сверьте число строк с количеством записей левой таблицы
  6. 6
    Проверьте суммы отдельным запросом к правой таблице, чтобы исключить задвоение

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

Итог

Что важно запомнить

Левое соединение гарантирует присутствие в результате всех записей левой таблицы; несовпавшие поля правой таблицы равны NULL. Обрабатывайте NULL через ЕСТЬNULL, не фильтруйте поля правой таблицы в секции ГДЕ и проверяйте результат на дубли по ключу связи.

Частые вопросы

Чем левое соединение отличается от правого в 1С?

Только порядком таблиц: правое соединение сохраняет все записи правой таблицы. Любой запрос с правым соединением можно переписать левым, поменяв таблицы местами. На практике правое соединение почти не используют — левое читается естественнее.

Почему после левого соединения пропали записи левой таблицы?

Почти всегда причина — условие по полю правой таблицы в секции ГДЕ. Такое условие отбрасывает строки, где поле равно NULL, то есть все несовпавшие записи. Перенесите условие в секцию ПО соединения или в параметры виртуальной таблицы.

Как заменить NULL на ноль или пустую строку?

Используйте функцию ЕСТЬNULL(Поле, ЗначениеПоУмолчанию): ЕСТЬNULL(Остатки.Количество, 0) для чисел или ЕСТЬNULL(Данные.Комментарий, "") для строк. Тип заменяющего значения должен быть совместим с типом поля.

Можно ли соединять одну таблицу с несколькими правыми?

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

Что быстрее — левое или внутреннее соединение?

При корректных индексах разница обычно несущественна; внутреннее соединение иногда выполняется быстрее, так как серверу не нужно сохранять несовпавшие строки. Выбирать тип соединения следует по смыслу задачи, а не по производительности — оптимизировать нужно индексы и отборы.

Как найти записи, которым нет пары в другой таблице?

Выполните левое соединение от основной таблицы к проверяемой и добавьте условие ГДЕ ПраваяТаблица.КлючевоеПоле ЕСТЬ NULL. В результат попадут только те записи левой таблицы, для которых соответствие не найдено.