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