Когда вы работаете с базами данных в 1С:Предприятие, рано или поздно сталкиваетесь с необходимостью объединять данные из нескольких таблиц. Один из самых востребованных типов соединений — левое соединение (или LEFT JOIN в SQL-синтаксисе). Оно позволяет получить все записи из «левой» таблицы, даже если для них нет соответствующих данных в «правой». Без понимания этого механизма сложно писать корректные запросы, особенно при работе со справочниками, документами и регистрами.

В этой статье мы разберём, что такое левое соединение в контексте 1С 8.3, как оно отличается от других типов соединений, и где его применять на практике. Вы узнаете про синтаксис в языке запросов , типичные ошибки начинающих разработчиков, а также получите готовые примеры кода для разных сценариев — от простых выборок до сложных отчётов. Особое внимание уделим нюансам производительности и оптимизации, которые критичны при работе с большими объёмами данных.

Что такое левое соединение и зачем оно нужно

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

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

  • 📌 Когда использовать: когда важны все записи из первой таблицы, даже без связей во второй.
  • 🔄 Альтернативы: внутреннее соединение (WHERE), полное внешнее (ПОЛНОЕ СОЕДИНЕНИЕ).
  • Производительность: может быть медленнее внутреннего, если правая таблица большая.

В левое соединение реализуется через конструкцию:

ЛЕВОЕ СОЕДИНЕНИЕ Таблица2 ПО Таблица1.Поле = Таблица2.Поле

Синтаксис левого соединения в языке запросов 1С

В отличие от классического SQL, где используется LEFT JOIN, в 1С:Предприятие 8 применяется конструкция ЛЕВОЕ СОЕДИНЕНИЕ. Рассмотрим базовый шаблон:

ВЫБРАТЬ

Таблица1.Поле1,

Таблица1.Поле2,

Таблица2.Поле3

ИЗ

Таблица1 КАК Таблица1

ЛЕВОЕ СОЕДИНЕНИЕ Таблица2 КАК Таблица2

ПО Таблица1.КлючевоеПоле = Таблица2.КлючевоеПоле

Ключевые моменты:

  • 🔑 После ЛЕВОЕ СОЕДИНЕНИЕ указывается правая таблица (та, данные которой могут отсутствовать).
  • 🔗 Условие соединения (ПО) определяет, как таблицы связываются между собой.
  • 📝 В результат попадают все записи из Таблица1, даже если для них нет соответствий в Таблица2.

Пример с реальными объектами :

ВЫБРАТЬ

Контрагенты.Наименование,

Заказы.Дата,

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

ИЗ

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

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

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

📊 Как часто вы используете левое соединение в запросах 1С?
Постоянно
Иногда
Редеко
Никогда

Отличие левого соединения от внутреннего и других типов

Чтобы понять, когда применять ЛЕВОЕ СОЕДИНЕНИЕ, важно сравнить его с другими типами объединения таблиц. Основные различия:

Тип соединения Синтаксис в 1С Что попадает в результат Пример использования
Левое ЛЕВОЕ СОЕДИНЕНИЕ Все записи из левой таблицы + совпадающие из правой (или NULL) Список всех товаров с остатками (включая те, что не в наличии)
Внутреннее ВНУТРЕННЕЕ СОЕДИНЕНИЕ или WHERE Только записи с совпадениями в обеих таблицах Заказы с оплатами (исключить неоплаченные)
Правое ПРАВОЕ СОЕДИНЕНИЕ Все записи из правой таблицы + совпадающие из левой Редко используется в 1С, заменяется левым с перестановкой таблиц
Полное внешнее ПОЛНОЕ СОЕДИНЕНИЕ Все записи из обеих таблиц (с NULL при отсутствии связей) Анализ всех возможных комбинаций данных

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

⚠️ Внимание: В 1С 8.2 и более ранних версиях синтаксис соединений мог отличаться. Для старых конфигураций проверьте совместимость в документации к вашей версии платформы.

Практические примеры использования

Рассмотрим реальные сценарии, где левое соединение незаменимо. Все примеры приведены для 1С:Управление торговлей 11, но адаптируются под другие конфигурации.

Пример 1: Товары с остатками и без

Задача: вывести список всех товаров из справочника, указав их остатки на складе (включая товары с нулевым остатком).

ВЫБРАТЬ

Товары.Наименование,

Товары.Артикул,

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

ИЗ

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

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

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

И Остатки.Склад = &ТекущийСклад

Пример 2: Контрагенты с последними заказами

Задача: показать всех контрагентов и дату их последнего заказа (если заказов не было — оставить пустое значение).

ВЫБРАТЬ

Контрагенты.Наименование,

МАКСИМУМ(Заказы.Дата) КАК ПоследнийЗаказ

ИЗ

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

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

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

СГРУППИРОВАТЬ ПО

Контрагенты.Наименование

Указаны все обязательные поля из левой таблицы|

Условие соединения (ПО) связывает ключевые поля|

Для полей правой таблицы предусмотрена обработка NULL (например, через ЕСТЬNULL)|

Запрос протестирован на пустых данных (когда связей нет)

-->

Пример 3: Сравнение плановых и фактических продаж

Задача: сопоставить плановые показатели продаж (из регистра сведений) с фактическими (из регистра накопления).

ВЫБРАТЬ

Планы.Товар.Наименование,

Планы.ПлановоеКоличество,

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

ИЗ

РегистрСведений.ПланыПродаж КАК Планы

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты КАК Факт

ПО Планы.Товар = Факт.Товар

И Факт.Период = &ТекущийМесяц

Типичные ошибки и как их избежать

Даже опытные разработчики иногда допускают ошибки при работе с левыми соединениями. Вот наиболее распространённые:

  • 🚫 Условия в WHERE для правой таблицы: Если вы добавляете фильтр по полю из правой таблицы в секцию ГДЕ, левое соединение превращается во внутреннее. Переносите такие условия в секцию ПО.
  • 🔄 Перепутан порядок таблиц: В левом соединении важно, какая таблица слева. Если перепутать местами, результат будет некорректным.
  • 📉 Игнорирование NULL: Поля из правой таблицы могут содержать NULL. Всегда обрабатывайте это через ЕСТЬNULL или ВЫРАЗИТЬ.

Пример неправильного запроса (условие для правой таблицы в ГДЕ):

ВЫБРАТЬ

Контрагенты.Наименование,

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

ИЗ

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

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

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

ГДЕ Заказы.Дата > &НачалоПериода // Ошибка! Это условие "обрежет" левое соединение

Исправленный вариант:

ВЫБРАТЬ

Контрагенты.Наименование,

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

ИЗ

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

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

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

И Заказы.Дата > &НачалоПериода // Условие перенесено в секцию ПО

⚠️ Внимание: В некоторых конфигурациях (например, 1С:ERP) регистры могут иметь сложную структуру. Перед использованием левого соединения проверьте, не требуется ли дополнительная фильтрация по измерениям или ресурсам через ГДЕ после соединения.

Оптимизация запросов с левым соединением

Левое соединение может замедлять выполнение запросов, особенно если правая таблица содержит миллионы записей. Вот как оптимизировать такие запросы:

  • 🛠️ Индексы: Убедитесь, что поля, используемые в условии ПО, проиндексированы. В индексы создаются автоматически для ключевых полей справочников и документов.
  • 📊 Фильтрация: Максимально сузьте выборку до соединения. Например, отфильтруйте контрагентов по региону перед соединением с заказами.
  • 🔗 Подзапросы: Для сложных условий используйте подзапросы в секции ПО, чтобы уменьшить объём соединяемых данных.

Пример оптимизированного запроса с предварительной фильтрацией:

ВЫБРАТЬ

Клиенты.Наименование,

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

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ

(ВЫБРАТЬ

Заказы.Контрагент,

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

ИЗ

Документ.ЗаказПокупателя КАК Заказы

ГДЕ

Заказы.Дата МЕЖДУ &НачалоПериода И &КонецПериода) КАК Заказы

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

💡

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

Для анализа производительности используйте План выполнения запроса в консоли запросов (Отладка → Показать план выполнения). Обратите внимание на:

  • 🔍 Полное сканирование таблиц (table scan) — признак отсутствия индексов.
  • 📈 Временные таблицы — их создание может указывать на неоптимальный план.

Левое соединение в отчётах и сложных выборках

В отчётах левое соединение часто применяется для:

  • 📅 Сравнительного анализа: например, сопоставление плановых и фактических данных.
  • 📊 Заполнения пропусков: чтобы в отчёте отображались все периоды, даже если по ним нет данных.
  • 🔄 Иерархических данных: вывод всех элементов справочника с данными по подчинённым объектам.

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

ВЫБРАТЬ

Месяцы.Дата КАК Месяц,

ЕСТЬNULL(Продажи.Количество, 0) КАК Количество

ИЗ

(ВЫБРАТЬ

ДОБАВИТЬКДАТЕ(&НачалоГода, МЕСЯЦ, ЧИСЛОМЕСЯЦЕВ(РАЗНОСТЬДАТ(&КонецГода, &НачалоГода, МЕСЯЦ))) КАК Дата

ИЗ

&Константа КАК Константа) КАК Месяцы

ЛЕВОЕ СОЕДИНЕНИЕ

(ВЫБРАТЬ

МЕСЯЦ(Документ.РеализацияТоваровУслуг.Дата) КАК Месяц,

СУММА(Документ.РеализацияТоваровУслуг.Количество) КАК Количество

ИЗ

Документ.РеализацияТоваровУслуг

ГДЕ

Документ.РеализацияТоваровУслуг.Дата МЕЖДУ &НачалоГода И &КонецГода

СГРУППИРОВАТЬ ПО

МЕСЯЦ(Документ.РеализацияТоваровУслуг.Дата)) КАК Продажи

ПО МЕСЯЦ(Месяцы.Дата) = Продажи.Месяц

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

Как ускорить отчёт с множеством левых соединений?

Используйте механизм ВРЕМЕННЫЕ ТАБЛИЦЫ для промежуточных результатов. Например:

1. Сначала сохраните данные из основной таблицы во временную таблицу.

2. Затем последовательно присоединяйте к ней другие таблицы.

Это снизит нагрузку на СУБД, особенно при работе с большими объёмами данных.

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

Иногда левое соединение — не лучший выбор. Рассмотрим альтернативы:

  • 🔄 Внутреннее соединение + UNION: Если нужно получить данные из обеих таблиц с приоритетом одной из них, можно использовать комбинацию внутреннего соединения и объединения (ОБЪЕДИНИТЬ).
  • 📝 Подзапросы в SELECT: Для простых случаев подзапрос в списке выборки может быть эффективнее.
  • 🛠️ Программная обработка: Если логика слишком сложна для SQL, иногда проще получить данные отдельными запросами и объединить их в коде на .

Пример с UNION:

ВЫБРАТЬ

Контрагенты.Наименование,

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

ИЗ

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

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

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

ОБЪЕДИНИТЬ

ВЫБРАТЬ

Контрагенты.Наименование,

NULL КАК СуммаДокумента

ИЗ

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

ГДЕ НЕ Контрагенты.Ссылка В (

ВЫБРАТЬ РАЗЛИЧНЫЕ Заказы.Контрагент

ИЗ Документ.ЗаказПокупателя КАК Заказы)

Такой подход может быть полезен, если:

  • 📌 Вам нужно явное управление тем, какие записи попадают в результат.
  • 📊 Требуется сложная логика заполнения отсутствующих данных.
⚠️ Внимание: В конфигурациях с большим количеством данных (например, 1С:Управление холдингом) чрезмерное использование UNION или подзапросов может привести к падению производительности. Всегда тестируйте альтернативные решения на реальных объёмах данных.
💡

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

FAQ: Частые вопросы по левому соединению в 1С

Можно ли в 1С использовать RIGHT JOIN вместо LEFT JOIN?

Технически да, но это не рекомендуется. В синтаксис ПРАВОЕ СОЕДИНЕНИЕ поддерживается, но его использование усложняет чтение кода. Лучше всегда использовать левое соединение, поменяв таблицы местами. Например, вместо ПРАВОЕ СОЕДИНЕНИЕ Таблица2 ПО.. пишите ЛЕВОЕ СОЕДИНЕНИЕ Таблица1 ПО.., где Таблица1 и Таблица2 поменялись ролями.

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

Наиболее вероятные причины:

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

Проверьте запрос без условий в ГДЕ и убедитесь, что соединение работает на тестовых данных.

Как обработать NULL в результатах левого соединения?

В для этого используйте функции:

  • ЕСТЬNULL(Поле, Замена) — возвращает Замена, если Поле равно NULL.
  • ВЫРАЗИТЬ(Поле КАК Тип) — преобразует NULL в значение по умолчанию для указанного типа (например, 0 для числа).

Пример:

ЕСТЬNULL(Заказы.СуммаДокумента, 0) КАК Сумма
Можно ли соединять более двух таблиц с помощью LEFT JOIN?

Да, в поддерживаются цепочки левых соединений. Например:

ВЫБРАТЬ

Контрагенты.Наименование,

Заказы.Дата,

Оплаты.Сумма

ИЗ

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

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

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

ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПоступлениеНаРасчетныйСчет КАК Оплаты

ПО Заказы.Ссылка = Оплаты.Заказ

При этом

Как левое соединение работает с виртуальными таблицами в 1С?

Левое соединение полностью поддерживается для виртуальных таблиц (например, РегистрНакопления.Остатки.Остатки). Однако есть нюансы:

  • Виртуальные таблицы часто содержат большие объёмы данных, поэтому соединение с ними может быть медленным.
  • Для виртуальных таблиц обязательно указывайте отборы по измерениям в секции ПО или ГДЕ, чтобы сузить выборку.

Пример:

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

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

И Остатки.Склад = &ТекущийСклад // Отбор по измерению