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