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

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

Полное соединение в запросе 1С: как работает и когда применять

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

Полное соединение (ПОЛНОЕ СОЕДИНЕНИЕ, FULL JOIN) — это тип соединения таблиц в языке запросов 1С, при котором в результат попадают все записи обеих таблиц, независимо от того, нашлась ли пара по условию связи. Там, где соответствия нет, поля «чужой» таблицы принимают значение NULL. Такой запрос отвечает на вопрос: «что есть в первой таблице, во второй и где они пересекаются» — в одной выборке.

На практике полное соединение чаще всего применяют для поиска расхождений между двумя источниками данных: например, между товарами на складе и позициями в прайсе, между проводками двух учётных систем или между справочником номенклатуры и остатками регистра. Это основной инструмент сверки данных в 1С.

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

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

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

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

Важно понимать, что полное соединение не «склеивает» таблицы физически и не меняет данные в базе — это только способ выборки. Результат существует в момент выполнения запроса и зависит от актуального состояния таблиц.

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

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

ТекстЗапроса =

"ВЫБРАТЬ

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

| Остатки.КоличествоОстаток КАК Остаток

|ИЗ

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

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

| ПО Номенклатура.Ссылка = Остатки.Номенклатура";

В этом примере в результат попадут: товары, по которым есть остатки; товары без остатков (поле Остаток будет NULL); и гипотетические остатки по номенклатуре, которой нет в справочнике (поле Товар будет NULL). Последняя ситуация редка при включённой ссылочной целостности, но возможна для виртуальных таблиц и временных таблиц.

Условие связи после ПО может содержать несколько предикатов через И, а также соединение по нескольким полям. Оператор ИЛИ в условии соединения допустим, но резко ухудшает производительность, так как оптимизатору сложнее построить план выполнения.

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

Выбор типа соединения определяет, какие строки вы увидите в результате. Ошибка в выборе типа — самая частая причина «пропавших» или «лишних» данных в отчётах.

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

Практическое правило: если задача формулируется как «покажи все записи таблицы А и подтяни данные из Б» — это левое соединение. Если формулировка звучит как «найди, что есть в А, но нет в Б, и наоборот» — это полное соединение.

Правое соединение в 1С встречается редко: большинство разработчиков предпочитают переставить таблицы местами и написать левое — так запрос читается единообразнее.

Сравнение вариантов

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

Подходит, когда важны все записи одной таблицы; не покажет «сирот» из правой таблицы

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

Подходит для двусторонней сверки; требует обработки NULL с обеих сторон и тяжелее для СУБД

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

Подходит для строгих пар; расхождения просто не попадут в результат и останутся незамеченными

Типовые сценарии: когда полное соединение действительно нужно

Сверка двух источников данных

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

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

Если добавить к полному соединению условие ГДЕ с проверкой на NULL по ключевому полю одной из таблиц, получите выборку только расхождений. Например, условие «Остатки.Номенклатура ЕСТЬ NULL ИЛИ Номенклатура.Ссылка ЕСТЬ NULL» оставит в результате только несовпавшие записи — это готовый отчёт о проблемах данных.

Объединение периодических срезов из разных источников

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

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

Работа с NULL: обязательная часть запроса с полным соединением

NULL в 1С — это не ноль и не пустая строка, а отсутствие значения. Любое сравнение с NULL даёт «ложь», арифметическая операция с NULL даёт NULL. Поэтому запрос с полным соединением без обработки NULL почти всегда работает неверно: суммы «теряются», условия не срабатывают, группировки дают неожиданные итоги.

Стандартный приём — функция ЕСТЬNULL(Поле, ЗначениеПоУмолчанию). Для числовых полей подставляйте 0, для строк — пустую строку, для ссылок — пустую ссылку соответствующего типа. Это делает дальнейшие вычисления и сравнения предсказуемыми.

В условии ГДЕ проверку на отсутствие записи выполняйте оператором ЕСТЬ NULL, а не сравнением «= NULL» — последнее синтаксически возможно, но семантически не работает так, как ожидает разработчик.

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

Производительность и ограничения

Полное соединение — самый тяжёлый тип соединения для СУБД: серверу нужно просмотреть обе таблицы целиком и сопоставить их содержимое, при этом эффективные планы выполнения ограничены. На больших таблицах (сотни тысяч записей и выше) такой запрос может выполняться заметно дольше левого соединения.

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

Ещё одно ограничение: в иерархических итогах и при работе с СКД полное соединение требует аккуратной настройки связей наборов данных — там оно моделируется через связи наборов, а не через текст запроса, и семантика отличается. Проверяйте результат на тестовых данных с заведомо известными расхождениями.

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

Надёжный способ проверки — подготовить контрольный пример: создайте в тестовой базе по одной записи каждого типа (есть пара, есть только слева, есть только справа) и убедитесь, что запрос возвращает ровно три строки с NULL в ожидаемых местах. Это занимает несколько минут, но сразу выявляет ошибки в условии связи.

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

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

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

Записи без пары из левой таблицы
Норма

Присутствуют, поля правой таблицы равны NULL

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

Записи отсутствуют — вероятно, использовано внутреннее соединение

Записи без пары из правой таблицы
Норма

Присутствуют, поля левой таблицы равны NULL

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

Записей нет — фактически работает левое соединение

Итоги по числовым полям
Норма

Суммы совпадают с суммами исходных таблиц

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

Итоги больше — перемножение строк из-за неуникального ключа

Время выполнения
Норма

Запрос отрабатывает за приемлемое время на реальном объёме

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

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

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

Можно ли заменить полное соединение объединением двух запросов?

Да, иногда полное соединение эмулируют через ОБЪЕДИНИТЬ двух выборок: левое соединение плюс записи правой таблицы без пары. Такой вариант иногда быстрее, но текст запроса становится сложнее и легче допустить ошибку в условиях. Если платформа и СУБД нормально справляются с ПОЛНОЕ СОЕДИНЕНИЕ, предпочтительнее использовать его.

Почему в результате полного соединения больше строк, чем в обеих таблицах вместе?

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

Работает ли полное соединение в СКД?

В тексте запроса набора данных СКД полное соединение использовать можно. Но при связи нескольких наборов данных в СКД применяется собственный механизм связей, который по умолчанию ведёт себя как левое соединение. Для двусторонней сверки корректнее собирать данные в одном наборе через запрос.

Как вывести в отчёте «нет в первой таблице» / «нет во второй таблице» вместо NULL?

Используйте конструкцию ВЫБОР с проверкой ЕСТЬ NULL: например, ВЫБОР КОГДА Остатки.Номенклатура ЕСТЬ NULL ТОГДА "Нет в остатках" ИНАЧЕ "ОК" КОНЕЦ. Это делает отчёт понятнее для пользователя, не знакомого с понятием NULL.

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

Да, в секции ИЗ допустимо несколько соединений подряд. Но семантика быстро усложняется: NULL из первого соединения участвует в следующем. На практике цепочки полных соединений редко оправданны — обычно задачу проще решить через временные таблицы.

Влияет ли порядок таблиц на результат полного соединения?

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

Итог

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

Полное соединение возвращает все записи обеих таблиц и заполняет отсутствующие поля значением NULL. Применяйте его для двусторонней сверки данных, всегда обрабатывайте NULL через ЕСТЬNULL и проверки ЕСТЬ NULL, а на больших объёмах предварительно фильтруйте данные во временных таблицах.