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