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