Соединения в запросах 1С объединяют строки таблиц по условию ПО: внутреннее оставляет только совпадения, левое сохраняет все строки слева и заполняет отсутствующие данные справа значением NULL. Главный риск не в синтаксисе, а в кратности связи: одна строка слева может превратиться в несколько строк результата.
Платформа поддерживает стандартные операции Join. Выбирайте левую таблицу как основу результата. Если нужен список всех товаров, даже без цен, Номенклатура должна стоять слева, а таблица цен справа. Если нужны только товары с ценой, подходит внутреннее соединение. Условие связи должно описывать ключ и, при необходимости, вид цены, период или организацию. Иначе совпадений становится больше, чем ожидается.
Оставляет только пары, для которых условие ПО истинно.
Сохраняет каждую строку левой таблицы.
Одна цена на товар или несколько записей по периодам.

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

Практика: соберите левое соединение товаров и цен и поймайте кратность
Откройте консоль запросов на тестовой копии базы и соберите запрос из статьи по частям: Справочник.Номенклатура как Товары слева, РегистрСведений.ЦеныНоменклатуры как Цены справа, связь по Товары.Ссылка = Цены.Номенклатура. Успех выглядит так: вы знаете точное количество строк на каждом шаге и можете сказать, где оно выросло и по какой причине. Боевую базу для этого трогать не нужно.
- Счёт строк до соединения. Выполните ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ Справочник.Номенклатура КАК Товары ГДЕ НЕ Товары.ПометкаУдаления и запишите число. Это основа результата: столько строк должно остаться после корректного левого соединения.
- ЛЕВОЕ СОЕДИНЕНИЕ с ценами. Допишите ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК Цены ПО Товары.Ссылка = Цены.Номенклатура и посчитайте строки заново. Если число выросло, у части товаров в регистре лежит несколько записей, и это кратность связи, а не ошибка синтаксиса.
- Условие ВидЦен внутри ПО. Добавьте в ПО через И условие Цены.ВидЦен = &ВидЦен и подставьте конкретный вид цен в параметр. Количество строк подойдёт ближе к числу из первого шага, а товары без такой цены останутся в выборке.
- ЕСТЬNULL и товары без цены. Выведите ЕСТЬNULL(Цены.Цена, 0) КАК Цена, затем отдельно выполните вариант с условием Цены.Номенклатура ЕСТЬ NULL. В первом запросе у товаров без записи стоит 0, во втором вы получаете список именно тех позиций, у которых цены нет.
- Переключение на ВНУТРЕННЕЕ. Замените ЛЕВОЕ на ВНУТРЕННЕЕ и сравните количество строк и набор товаров с прошлым запуском. Разница равна ровно тем позициям, у которых нет записи по заданному виду цен.
Теперь сломайте запрос намеренно. Перенесите условие Цены.ВидЦен = &ВидЦен из ПО в ГДЕ и выполните заново: товары без цены пропадут, потому что NULL не проходит фильтр, и левое соединение начнёт работать как внутреннее. Второй эксперимент: уберите условие по виду цен и поставьте РАЗЛИЧНЫЕ, чтобы спрятать дубли. Как только вы выведете саму цену, товар снова задвоится: строки с разными ценами остаются разными, а кратность связи никуда не делась.
Дальше замените прямое обращение к регистру на виртуальную таблицу СрезПоследних на нужную дату и посмотрите, как уходит кратность по периодам. Другой путь: соберите уникальный набор цен во временной таблице с группировкой по номенклатуре и соединяйтесь уже с ней. Когда добавите третий источник, например остатки, считайте строки после каждого соединения, а не в самом конце. Проверенный запрос затем перенесите в набор данных отчёта на СКД.
Частые ошибки и почему они появляются
Самая частая ошибка: удалить дубли инструкцией РАЗЛИЧНЫЕ и считать задачу решённой. Инструкция РАЗЛИЧНЫЕ скрывает симптом, но не объясняет кратность. Вторая ошибка: условия правой таблицы помещены в ГДЕ после левого соединения. Третья: сравниваются поля несовместимых типов или разные сущности с похожими названиями. Проверяйте ключи.
Сначала найдите связь, которая умножает строки.
Если строка без пары нужна, условие правой таблицы оставьте в ПО.
Сравните количество ключей до и после каждого соединения.
Самопроверка
Что сохраняет левое соединение в запросе 1С?
Левое соединение сохраняет каждую строку левой таблицы, даже когда справа подходящей пары нет. Поля правой таблицы в таких строках заполняются значением NULL, поэтому в результате остаются все товары, включая позиции без цены.
Чем ВНУТРЕННЕЕ соединение отличается от ЛЕВОГО?
Внутреннее соединение оставляет только пары, для которых условие ПО истинно, а левое оставляет всю левую таблицу целиком. Нужен список всех товаров, даже без цен, ставьте Номенклатуру слева и берите ЛЕВОЕ; нужны только товары с ценой, подходит ВНУТРЕННЕЕ.
Убирает ли ЕСТЬNULL дубли строк?
Функция ЕСТЬNULL дубли не убирает: она подставляет значение вместо отсутствующего, например 0 вместо пустой цены. Лишние строки появляются из-за кратности связи, и искать их нужно в правой таблице, сгруппировав её по ключу.
Почему после соединения выросло число строк?
Число строк растёт, когда одной записи слева соответствует несколько записей справа: в периодическом регистре на товар может лежать несколько цен одного вида по разным периодам. Сравните количество ключей до и после соединения, найдите правую таблицу с кратностью и сверните её через СрезПоследних или временную таблицу.
Почему условие по правой таблице нельзя переносить в ГДЕ?
Условие правой таблицы в ГДЕ отсекает строки, для которых пары не нашлось: там поле равно NULL, а NULL фильтр не проходит. Левое соединение из-за этого фактически превращается во внутреннее, поэтому условие вида Цены.ВидЦен = &ВидЦен пишут в ПО.
Как найти товары, у которых нет цены?
Товары без цены находят левым соединением с проверкой правого ключа: условие Цены.Номенклатура ЕСТЬ NULL оставляет только позиции без пары в регистре. Полное соединение для такой задачи не нужно, оно лишь усложняет чтение ключа.
Что делать дальше
Постройте внутренний и левый варианты одного запроса и сравните набор ключей. Базовые алгоритмы закрепляются на курсе SQL. Если синтаксис пока непривычен, вернитесь к введению в язык запросов, затем примените Join в отчёте СКД.
