Почему левое соединение с табличной частью документа работает как внутреннее в 1С

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

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

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

Разберем ключевые факторы, из-за которых в итоговой выборке исчезают документы с незаполненной или отсутствующей табличной частью:

  1. Условия на реквизиты правой таблицы в секции ГДЕ. Если в блоке ГДЕ указывается фильтр по полю из присоединяемой правой таблицы (например, ГДЕ ТЧ.РеквизитТЧ = &Значение), то при отсутствии строк в ТЧ поле возвращает NULL. Любое сравнение NULL с конкретным значением возвращает Ложь, в результате чего весь документ отсекается из результата выборки.
  2. Неявные соединения (разыменование полей через точку). При обращении через точку к реквизитам шапки документа от присоединяемой табличной части (например, МойДокументТЧ.Ссылка.Организация или МойДокументТЧ.Ссылка.Ссылка) платформенная система оптимизации транслирует данное обращение в неявное внутреннее соединение на уровне СУБД. В результате строки с NULL удаляются из итогового результата.
  3. Ограничения прав на уровне записей (RLS). Если для присоединяемой табличной части действуют правила RLS, платформа автоматически встраивает подзапросы. Если правила RLS не обрабатывают NULL, они могут отсечь строки левой таблицы.
  4. Особенности работы консоли запросов. Некоторые консоли запросов при выгрузке результата во внутренние структуры (дерево значений или сгруппированные таблицы) могут визуально скрывать строки, у которых все поля правой таблицы равны NULL, создавая ложное впечатление работы внутреннего соединения.

Разница между обращениями к полям Ссылка и Ссылка.Ссылка

Рассмотрим частую ошибку при составлении условий связи по полю Ссылка табличной части. Поле Ссылка в табличной части документа уже содержит прямую ссылку на документ-владелец. Разберем разницу на примере:

Конструкция связи вида:

ПО вт.Ссылка = МойДокументТЧ.Ссылка

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

ПО вт.Ссылка = МойДокументТЧ.Ссылка.Ссылка

заставляет платформу выполнить повторное неявное соединение с таблицей шапки документа через точку, что может привести к изменению плана выполнения запроса на уровне СУБД и отсечению записей с NULL.

Правильный вариант построения запроса с использованием временных таблиц

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

Шаг 1. Выбираем ссылки и реквизиты шапки документов во временную таблицу:


ВЫБРАТЬ
	УчетРаботы.Ссылка КАК Ссылка,
	УчетРаботы.Организация КАК Организация
ПОМЕСТИТЬ втДокументы
ИЗ
	Документ.УчетРаботы КАК УчетРаботы
ГДЕ
	УчетРаботы.Дата МЕЖДУ &Дата1 И &Дата2
	И УчетРаботы.Проведен;

Шаг 2. Выполняем левое соединение основной временной таблицы с табличной частью документа и обрабатываем возможные значения NULL с помощью функции ЕСТЬNULL:


ВЫБРАТЬ
	втДокументы.Ссылка КАК Ссылка,
	втДокументы.Организация КАК Организация,
	ЕСТЬNULL(УчетРаботыФакт.Выполнено, 0) КАК Выполнено
ИЗ
	втДокументы КАК втДокументы
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.УчетРаботы.Факт КАК УчетРаботыФакт
		ПО втДокументы.Ссылка = УчетРаботыФакт.Ссылка;

Рекомендации по работе с левым соединением в 1С

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