❓ 7.6 Вложенный запрос может использоваться:
📚 Документация
Заголовок раздела «📚 Документация»-
ИТС: Язык запросов «1С:Предприятия 8» — Как использовать данные одного запроса внутри другого запроса.
-
ИТС: Язык запросов «1С:Предприятия 8» — Соединения с вложенными запросами.
-
ИТС: Стандарты разработки — Ограничения на соединения с вложенными запросами и виртуальными таблицами.
-
ИТС: Стандарты разработки — Ограничения на использование вложенных запросов в условии соединения.
🧠 Краткая теория
Заголовок раздела «🧠 Краткая теория»Что такое вложенный запрос
Заголовок раздела «Что такое вложенный запрос»Вложенный запрос — это запрос, находящийся внутри другого запроса. Получаемая им выборка используется при выполнении внешнего запроса.
Вложенные запросы позволяют сначала сформировать необходимые данные, а затем использовать их в другом запросе.
Где может использоваться вложенный запрос
Заголовок раздела «Где может использоваться вложенный запрос»Вложенный запрос может участвовать в запросе несколькими способами.
Как источник данных
Заголовок раздела «Как источник данных»Результат вложенного запроса может выступать источником данных внешнего запроса:
ВЫБРАТЬ Продажи.Номенклатура, Продажи.КоличествоИЗ (ВЫБРАТЬ РеализацияТовары.Номенклатура КАК Номенклатура, СУММА(РеализацияТовары.Количество) КАК Количество ИЗ Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТовары СГРУППИРОВАТЬ ПО РеализацияТовары.Номенклатура) КАК ПродажиЗдесь результат вложенного запроса получает имя Продажи и становится источником данных внешнего запроса.
Как одна из соединяемых выборок
Заголовок раздела «Как одна из соединяемых выборок»Результат вложенного запроса может участвовать в соединении с другим источником:
ВЫБРАТЬ Номенклатура.Ссылка, Продажи.КоличествоИЗ Справочник.Номенклатура КАК Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ РеализацияТовары.Номенклатура КАК Номенклатура, СУММА(РеализацияТовары.Количество) КАК Количество ИЗ Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТовары СГРУППИРОВАТЬ ПО РеализацияТовары.Номенклатура) КАК Продажи
ПО Номенклатура.Ссылка = Продажи.НоменклатураЗдесь вложенный запрос Продажи является одной из соединяемых выборок.
В секции ГДЕ
Заголовок раздела «В секции ГДЕ»Вложенный запрос может использоваться в условии отбора, например с оператором В:
ВЫБРАТЬ Товары.СсылкаИЗ Справочник.Номенклатура КАК ТоварыГДЕ Товары.Ссылка В (ВЫБРАТЬ Остатки.Номенклатура ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки() КАК Остатки)Вложенный запрос формирует множество значений, которое используется внешним запросом при проверке условия В.
В условии соединения ПО
Заголовок раздела «В условии соединения ПО»Вложенный запрос может находиться непосредственно в условии соединения:
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Цены КАК ЦеныПО Цены.Номенклатура = Товары.Номенклатура И Цены.Период В (ВЫБРАТЬ МАКСИМУМ(ПредыдущиеЦены.Период) ИЗ РегистрСведений.Цены КАК ПредыдущиеЦены ГДЕ ПредыдущиеЦены.Номенклатура = Товары.Номенклатура)Здесь вложенный запрос не является отдельным источником соединения — он входит непосредственно в выражение ПО.
В параметрах виртуальной таблицы
Заголовок раздела «В параметрах виртуальной таблицы»Вложенный запрос может использоваться в выражении, передаваемом в параметры виртуальной таблицы.
Например, условие виртуальной таблицы может содержать проверку вхождения в результат вложенного запроса:
РегистрНакопления.ТоварыНаСкладах.Остатки( , Номенклатура В (ВЫБРАТЬ Товары.Номенклатура ИЗ Документ.РеализацияТоваровУслуг.Товары КАК Товары))В этом случае вложенный запрос является частью условия, передаваемого в параметр виртуальной таблицы.
Вложенный запрос и временная таблица
Заголовок раздела «Вложенный запрос и временная таблица»Вложенные запросы и временные таблицы позволяют решать похожую задачу — получать промежуточные данные для дальнейшей обработки. Но механизм их использования различается.
| Вложенный запрос | Временная таблица |
|---|---|
| Находится внутри другого запроса | Промежуточный результат помещается во временную таблицу |
| Результат используется непосредственно во внешнем запросе | Временную таблицу можно использовать в последующих запросах |
| Отдельная индексация промежуточного результата не задается | Для временной таблицы можно задать индекс с помощью ИНДЕКСИРОВАТЬ ПО |
Поэтому вложенный запрос и временная таблица — не полностью взаимозаменяемые механизмы. Во многих задачах одну и ту же промежуточную выборку можно получить обоими способами, но способ выполнения запроса будет различаться.
Ограничения по производительности
Заголовок раздела «Ограничения по производительности»Возможность использовать вложенный запрос в определенной конструкции языка запросов не означает, что эта конструкция рекомендуется с точки зрения производительности.
Для некоторых случаев стандарты разработки 1С содержат отдельные ограничения.
Соединение с вложенным запросом
Заголовок раздела «Соединение с вложенным запросом»📐 Стандарт «Ограничения на соединения с вложенными запросами и виртуальными таблицами» — #std655:
Речь идет о конструкции, в которой результат вложенного запроса является одной из соединяемых выборок:
ИЗ Справочник.Номенклатура КАК Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ ... ) КАК Продажи
ПО Номенклатура.Ссылка = Продажи.НоменклатураДля выбора способа соединения оптимизатору СУБД необходимо оценить количество записей в соединяемых выборках.
Для физических таблиц СУБД может использовать имеющуюся статистику. Оценить количество записей, которое вернет вложенный запрос, может быть сложнее.
Физическая таблица
↓
СУБД может оценить объем выборки
на основании имеющейся статистики
↓
Проще выбрать способ соединения
Вложенный запрос
↓
Количество возвращаемых записей
оценить сложнее
↓
Оптимизатор может ошибиться
при выборе способа соединения
↓
Возможен неоптимальный план выполнения
Стандарт рекомендует вместо соединения с вложенным запросом использовать соединение с временной таблицей, если вложенный запрос не выбирает заведомо небольшое количество записей.
Вложенный запрос в условии соединения
Заголовок раздела «Вложенный запрос в условии соединения»📐Стандарт «Ограничения на использование вложенных запросов в условии соединения» — #std656:
Здесь ситуация другая: соединяемым источником является обычная таблица, но вложенный запрос находится непосредственно в условии ПО:
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Цены КАК ЦеныПО Цены.Номенклатура = Товары.Номенклатура И Цены.Период В (ВЫБРАТЬ ... )Стандарт рекомендует не использовать вложенные запросы в условиях соединения. Такая конструкция может привести к значительному замедлению выполнения запроса, а в отдельных случаях — к его неработоспособности на некоторых СУБД.
Для таких случаев запрос рекомендуется переписать с использованием временных таблиц.
#std655
Вложенный запрос — источник соединения
СОЕДИНЕНИЕ
(ВЫБРАТЬ ...) КАК Данные
ПО ...
#std656
Вложенный запрос — внутри условия соединения
СОЕДИНЕНИЕ Таблица
ПО Поле В
(ВЫБРАТЬ ...)
Обе конструкции допускаются языком запросов, но для обеих существуют отдельные рекомендации по производительности.
🧠 Ключевая мысль
Заголовок раздела «🧠 Ключевая мысль»Вложенный запрос позволяет использовать результат одного запроса внутри другого: как источник данных, как одну из соединяемых выборок, в секции ГДЕ, в условии соединения ПО и в выражениях, передаваемых в параметры виртуальных таблиц.
При этом возможность использовать вложенный запрос нужно отличать от рекомендаций по производительности: стандарты разработки отдельно ограничивают соединения с вложенными запросами (#std655) и использование вложенных запросов в условиях соединения (#std656).