Вложенные запросы. Вложенные запросы Работа с пакетными запросами

Вложенные запросы. Вложенные запросы Работа с пакетными запросами

Данная статья рассчитана на читателей, которые знакомы с языком SQL.

Язык запросов в 1С, применяющийся начиная с версии 8, сегодня стал полезным инструментом для работы с базами данных, который позволяет читать из них, но не записывать. Синтаксически язык запросов очень схож с языком SQL, но на русском языке.

Ниже представлена таблица соответствия основных операторов языка запросов и SQL:

Операторы языка запросов 1С

Оператор SQL

РАЗЛИЧНЫЕ

СОЕДИНЕНИЕ

СГРУППИРОВАТЬ ПО

ОБЪЕДИНИТЬ

УПОРЯДОЧИТЬ ПО

И это далеко не полный список. Более полную справочную информацию по доступным операторам языка запросов можно получить в конструкторе запросов, о котором будет рассказано ниже.

Выполнение запроса 1С из программного кода осуществляется при помощи объекта встроенного языка «Запрос». Пример написания запроса к базе данных с использованием встроенного языка программирования:

Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Синоним.Ссылка КАК Ссылка |ИЗ | Справочник.Справочник1 КАК Синоним"; Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл // Вставить обработку выборки ВыборкаДетальныеЗаписи КонецЦикла;

Метод «Выполнить» выполняет запрос, метод «Выбрать» возвращает значение типа «ВыборкаИзРезультатаЗапроса». Также можно использовать метод «Выгрузить», который возвращает таблицу значений.

Параметры запроса хранятся в свойстве «Параметры» (в данном случае это структура, поэтому все методы структуры тут применимы – вставить, удалить и т.д.).

Пример установки параметра «Запрос.Параметры.Вставить» («Справочник», СправочникСсылка). В запросе обратиться к параметрам можно через амперсанд «&Справочник». Ниже пример запроса с использованием параметров:

Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Пользователи.Ссылка КАК Ссылка, | Пользователи.Родитель КАК Родитель, | Пользователи.Наименование КАК Наименование |ИЗ | Справочник.Пользователи КАК Пользователи |ГДЕ | Пользователи.Ссылка = &Справочник"; Запрос.Параметры.Вставить("Справочник", СправочникСсылка); Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл // Вставить обработку выборки ВыборкаДетальныеЗаписи КонецЦикла;

Напомним, что язык запросов предназначен только для чтения данных из базы, поэтому в нем отсутствуют аналоги таких операторов SQL, как INS ERT и UPDATE. Данные можно модифицировать только через объектную модель встроенного языка программирования 1С. Также в языке запросов 1С существуют операторы, аналогов которых нет в SQL, например:

  • В ИЕРАРХИИ
  • ПОМЕСТИТЬ
  • ИНДЕКСИРОВАТЬ ПО

В ИЕРАРХИИ – позволяет выбрать все элементы иерархического справочника, которые входят в иерархию переданной ссылки. Пример запроса с использованием В ИЕРАРХИИ :

ВЫБРАТЬ Товары.Ссылка, Товары.Артикул ИЗ Справочник.Товары КАК Товары ГДЕ Товары.Ссылка В ИЕРАРХИИ(&Цитрусовые)"

В данном случае в результат вернутся все подчиненные элементы справочника номенклатуры «Цитрусовые», неважно, сколько уровней иерархии есть у данного справочника.

Также, к примеру, стоит задача найти товар с именем «Ручка». Товар должен входить в иерархию «Канц. Товаров», то есть нам не надо искать дверную ручку. Структура номенклатуры в этом случае такова:

Канцелярия

|_ Ручки перьевые |_ Ручка красная |_ Ручка синяя |_ Ручки чернильные |_ Линейки

Фурнитура

|_ Ручки дверные |_ Ручка дверная простая |_ Ручка дверная люкс

Пишем такой запрос:

ВЫБРАТЬ Товары.Ссылка, Товары.Артикул ИЗ Справочник.Товары КАК Товары ГДЕ Товары.Наименование Подобно "Ручка%" И Товары.Ссылка В ИЕРАРХИИ(&Канцелярия)"

При использовании конструкции В ИЕРАРХИИ необходимо учитывать, что если в параметр «Канцелярия» передать пустую ссылку, выполнение запроса замедлится, так как платформа будет проверять каждый элемент на принадлежность корню.

ПОМЕСТИТЬ – Данный оператор помещает результат во временную таблицу. Пример запроса:

ВЫБРАТЬ Пользователи.Ссылка КАК Ссылка, Пользователи.Родитель КАК Родитель, Пользователи.Наименование КАК Наименование ПОМЕСТИТЬ ОтобранныеПользователи ИЗ Справочник.Пользователи КАК Пользователи ГДЕ Пользователи.Ссылка = &Справочник; ВЫБРАТЬ ОтобранныеПользователи.Ссылка КАК Ссылка, ОтобранныеПользователи.Родитель КАК Родитель, ОтобранныеПользователи.Наименование КАК Наименование ИЗ ОтобранныеПользователи КАК ОтобранныеПользователи

Данный запрос на SQL будет выполнен несколькими запросами:

  • Создание временной таблицы (платформа умеет «переиспользовать» ранее созданные временные таблицы, поэтому создание происходит не всегда);
  • Помещение данных во временную таблицу;
  • Выполнение основного запроса, а именно SEL ECT из этой временной таблицы;
  • Уничтожение/очистка временной таблицы.

Временная таблица может быть уничтожена явно, через конструкцию УНИЧТОЖИТЬ , либо неявно – при закрытии менеджера временных таблиц.

У объекта «Запрос» встроенного языка программирования есть свойство «МенеджерВременныхТаблиц», которое предназначено для работы с временными таблицами. Пример кода:

МВТ = Новый МенеджерВременныхТаблиц(); Запрос = Новый Запрос; Запрос.МенеджерВременныхТаблиц = МВТ;

После выполнения запроса переменную МВТ можно использовать второй раз в другом запросе, что, несомненно, является еще одним плюсом использования временных таблиц. В данном случае временная таблица из базы будет удалена при вызове метода «Закрыть»…

МВТ.Закрыть();

…или же при очистке переменной из памяти, то есть при выполнении метода, в котором переменная была объявлена. Временные таблицы повышают нагрузку на дисковую подсистему, поэтому не следует создавать очень много временных подсистем (в цикле, например), или подсистем большого объема.

ИНДЕКСИРОВАТЬ ПО – этот оператор применяется совместно с оператором ПОМЕСТИТЬ. При создании временной таблицы этим оператором можно проиндексировать создаваемую таблицу, что существенно ускоряет работу с ней (но только, если индекс подходит под ваш запрос).

Бесплатная консультация эксперта

Спасибо за Ваше обращение!

Специалист 1С свяжется с вами в течение 15 минут.

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

ДЛЯ ИЗМЕНЕНИЯ – данный оператор предназначен для блокировки определенной таблицы запроса (или всех таблиц, которые участвуют в запросе). Блокировка осуществляется наложением U блокировки на таблицу. На SQL это реализуется через hint UPDLOCK. Данная конструкция необходима для предотвращения блокировок типа deadlock. Пример запроса с конструкцией ДЛЯ ИЗМЕНЕНИЯ:

ВЫБРАТЬ Пользователи.Ссылка КАК Ссылка, Пользователи.Родитель КАК Родитель, Пользователи.Наименование КАК Наименование ИЗ Справочник.Пользователи КАК Пользователи ЛЕВОЕ СОЕДИНЕНИЕ Справочник.РФК КАК РФК ПО Пользователи.РФК = РФК.Ссылка ДЛЯ ИЗМЕНЕНИЯ Справочник.Пользователи

В данном примере U блокировка будет установлена на таблицу «Пользователи». Если не указывать таблицу для блокировки, она будет наложена на все таблицы, участвующие в запросе. Важно отметить, что данная конструкция работает только в конфигурациях, в которых включен автоматический режим управления блокировками.



СОЕДИНЕНИЕ – запрос поддерживает соединения ЛЕВОЕ/ПРАВОЕ, ПОЛНОЕ, ВНУТРЕННЕЕ, что соответствует соединениям в SQL – LEFT/RIGHT JOIN, OUTER JOIN, INNER JOIN.

Однако при использовании конструктора запросов вы не сможете сделать ПРАВОЕ СОЕДИНЕНИЕ. Конструктор просто будет менять местами таблицы, но оператор будет всегда левый. По этой причине в 1С никогда не встретишь применения правого соединения.

Синтаксически соединение выглядит так:

ВЫБРАТЬ Таблица1.Ссылка КАК Ссылка ИЗ Справочник.Справочник1 КАК Таблица1 ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Справочник2 КАК Таблица2 ПО Таблица1.Реквизит = Таблица2.Реквизит

В языке запросов 1С отсутствует оператор для соединения декартова произведения (CROSS JOIN). Однако отсутствие оператора не означает, что язык запросов не поддерживает такого соединения. Соединить таблицы при необходимости можно таким образом:

ВЫБРАТЬ Таблица1.Ссылка КАК Ссылка ИЗ Справочник.Справочник1 КАК Таблица1 ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Справочник2 КАК Таблица2 ПО ИСТИНА

Как видно из примера, задан ключ соединения ПО ИСТИНА , то есть каждая строка одной таблицы соответствует строке другой. Тип соединения (ЛЕВОЕ, ПРАВОЕ, ПОЛНОЕ, ВНУТРЕННЕЕ) не важен, если у вас есть строки в обеих таблицах, но если в какой-то из таблиц нет строк (пуская таблица) – результат будет отличаться. Например, при использовании ВНУТРЕННЕЕ соединение результат будет пустой. При использовании ЛЕВОЕ/ПРАВОЕ соединение в результате будет или не будет данных в зависимости от того, к какой таблице мы присоединяемся – с данными или нет. При использовании ПОЛНОГО соединения данные будут всегда (естественно, только одной таблицы, так как в другой пустота), выбор типа соединения зависит от конкретной прикладной задачи.

Небольшая визуальная подсказка, как работают различные типы соединений:



ПОДОБНО. В отличие от аналогичного оператора языка SQL – LIKE, шаблон для ПОДОБНО можно задать, используя только некоторые спец символы:

  • % (процент): последовательность, содержащая любое количество произвольных символов;
  • _ (подчеркивание): один произвольный символ;
  • / - следующий символ нужно интерпретировать как обычный символ.

ИТОГИ ПО аналогом на SQL можно назвать оператор ROLLUP. Пример использования оператора ИТОГИ:

ВЫБРАТЬ Товары.Цена КАК Цена, Товары.Товар КАК Товар ИЗ Справочник.Номенклатура КАК Товары ИТОГИ СРЕДНЕЕ(Цена) ПО Товар

Результат будет такой:

Кровать

9833,333

Утюг

Ручка

То есть в результат добавляется дополнительная строка, содержащая значение поля, по которому производится группировка и значение агрегирующей функции.

Работа с пакетными запросами

1С позволяет работать с пакетами запросов. В пакетном запросе тексты запросов разделяются точкой с запятой (;). Выполнение пакетного запроса 1С осуществляется последовательно. Пример текста пакетного запроса:

ВЫБРАТЬ Пользователи.Ссылка КАК Ссылка, Пользователи.Родитель КАК Родитель, Пользователи.Наименование КАК Наименование ИЗ Справочник.Пользователи КАК Пользователи;
ВЫБРАТЬ ГрафикРаботы.Пользователь КАК Пользователь, ГрафикРаботы.Дата КАК Дата, ГрафикРаботы.РабочихЧасов КАК РабочихЧасов ИЗ РегистрСведений.ГрафикРаботы КАК ГрафикРаботы

Для получения результата всех запросов, входящих в пакет, необходимо воспользоваться методом объекта запроса «ВыполнитьПакет», вместо «Выполнить». Данный метод последовательно выполняет все запросы. Результат запроса – массив результатов для каждого запроса из пакета, а последовательность расположения в массиве такая же, как последовательность запросов в тексте пакета.

Рассматривая язык запросов, стоит упомянуть о такой особенности, как виртуальные таблицы. Виртуальные таблицы отсутствуют в базе данных, это своеобразная обертка, которая выполняется на стороне СУБД как запрос с использованием подзапросов. Пример запроса 1С с использованием виртуальных таблиц:

ВЫБРАТЬ РегистрОбязательствОбороты.Обязательство КАК Обязательство ИЗ РегистрНакопления.РегистрОбязательств.Обороты() КАК РегистрОбязательствОбороты

Такой запрос на СУБД будет выглядеть так:

SEL ECT T1.Fld25931RRef FR OM (SELECT T2._Fld25931RRef AS Fld25931RRef, CAST(SUM(T2._Fld25936) AS NUMERIC(38, 8)) AS Fld25936Turnover_, CAST(SUM(T2._Fld25937) AS NUMERIC(38, 8)) AS Fld25937Turnover_ FR OM dbo._AccumRgTn25938 T2 WH ERE ((T2._Fld949 = @P1)) AND ((T2._Fld25936 @P2 OR T2._Fld25937 @P3)) GROUP BY T2._Fld25931RRef HAVING (CAST(SUM(T2._Fld25936) AS NUMERIC(38, 8))) 0.0 OR (CAST(SUM(T2._Fld25937) AS NUMERIC(38, 8))) 0.0) T1>>>>

Видно, что не похоже на SQL, поскольку есть подзапрос, группировка. Виртуальные таблицы, по большому счету – это «синтаксический сахар», то есть созданы, в общем-то, для удобства разработки запросов, чтобы запросы были компактнее и читабельнее.

Виртуальные таблицы есть только у регистров, но какие именно виртуальные таблицы доступны у регистра, можно увидеть в конструкторе запросов.



При использовании виртуальных таблиц необходимо всегда давать условие отбора. В противном случае могут возникнуть проблемы с производительностью.



В тексте запроса это выглядит так:

РегистрНакопления.РегистрОбязательств.Обороты(, Операция = &Операция) КАК РегистрОбязательствОбороты

Для удобства написание запросов, то есть создания текстов запросов, в 1С существует конструктор, который можно вызвать через контекстное меню (правой кнопкой мыши):



В конструкторе запросов можно увидеть полный список поддерживаемых функций и операторов языка запросов.


Конструктор запросов является очень гибким визуальным инструментом для создания запросов любой сложности. Он доступен только в режиме конфигуратора. В режиме Предприятия есть так называемая «Консоль запросов» – это внешняя обработка, поставляемая на диске ИТС. Для управляемого приложения консоль запросов можно скачать на сайте its.1c.ru.

Описание работы в конструкторе запросов выходит за рамки тематики данной статьи, поэтому подробно рассматриваться не будет.

Причины неоптимальной работы запросов

Ниже приведен список основных причин (но не всех), которые приводят к замедлению выполнения запроса.

  • Использования соединения с подзапросами

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

  • Использование виртуальных таблиц в соединениях запроса

Виртуальные таблицы на уровне СУБД выполняются как подзапросы, поэтому причины такие же, как в первом пункте.

  • Использование условий в запросе, неподходящих под существующие индексы

Если в условиях запроса (в операторе ГДЕ или в условиях виртуальной таблицы) используются поля, которые не все входят в индекс, данный запрос будет выполнен с использованием SQL конструкции table scan или index scan (полностью или частично). Это скажется не только на времени выполнения запроса, но также будет наложена избыточная S блокировка на лишние строки, что в свою очередь может привести к эскалации блокировок, то есть будет заблокирована вся таблица.

  • Использование ИЛИ в условиях запроса

Использование логического оператора ИЛИ в конструкции ГДЕ может также приводить к сканированию таблицы (table scan). Это происходит из-за того, что СУБД не может корректно использовать индекс. Вместо ИЛИ можно применить конструкцию ОБЪЕДИНИТЬ ВСЕ.

  • Получение данных через точку для полей составного типа

Не рекомендуется получать значения через точку (в конструкции ВЫБРАТЬ, ГДЕ ), поскольку если реквизит объекта окажется составным типом, соединение будет происходить с каждой таблицей, входящей в этот составной тип. В результате запрос на СУБД будет значительно усложнен, это может помешать оптимизатору в выборе корректного плана выполнения запроса.

Из базы данных по некоему условию. Для этого в 1С 8.3 необходимо использовать вложенные запросы.

Но следует учитывать, что в большинстве случаев вложенные запросы в 1С бесполезны без соединения их результата с другими таблицами. Такое соединение практически в любом случае приведет к сильному замедлению выполнения запроса в целом.

Пример вложенного запроса на языке запросов

Приведу пример вложенного запроса на . Допустим, нам нужно сделать выборку суммы некоторого остатка по отдельным клиентам на определенную дату:

ВЫБРАТЬ
НераспОплатыОстатки.Заказчик,
НераспОплатыОстатки.СуммаОст
ИЗ

Получите 267 видеоуроков по 1С бесплатно:

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления. НераспОплаты.Остатки КАК НераспОплаты
ПО ВложЗапрос.СсылкаНаСпрЗаказчики = НераспОплатыОстатки.Заказчик

Когда СУБД будет выполнять такой запрос, не исключены неверные действия оптимизатора, так как трудно определиться с планом обработки запроса. Когда СУБД соединяет две таблицы, оптимизатор строит алгоритм на основе вычисления количества записей в этих таблицах.

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

Как лучше?

// Временная таблица
ВЫБРАТЬ
Заказчики.Ссылка КАК Заказчики
ПОМЕСТИТЬ табЗаказчики
ИЗ
Справочник.Заказчики КАК Заказчики
ГДЕ Заказчики.Ссылка В (&Заказчики)
;

// Основной запрос
ВЫБРАТЬ
табКлиенты.Ссылка,
НераспОплатыОстатки.СуммаОст,
ИЗ
табЗаказчики КАК табЗаказчики
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.НераспОплаты.Остатки(
,
Заказчик В
(ВЫБРАТЬ
табЗаказчики.Заказчики
ИЗ
табЗаказчики)) КАК НераспОплатыОстатки
ПО табЗаказчики.Заказчики = НераспОплатыОстатки.Заказчики

Смотрите также видео-урок про вложенные запросы:

Теперь оптимизатор знает заранее, сколько записей во временной таблице, и без труда оптимизирует алгоритм выполнения соединения таблиц.

Если Вы начинаете изучать 1С программирование, рекомендуем наш бесплатный курс (не забудьте

Конструктор запросов в 1С 8.3 и 8.2 — мощнейший инструмент разработки. Он позволяет составить текст запроса при помощи специальной визуальной среды. Таким образом, чтобы создать запрос 1с не обязательно знать встроенный язык запросов, достаточно ориентироваться в не сложном и интуитивно понятном интерфейсе конструктора.

Конструктор запросов представляет из себя набор вкладок, каждая из которых отвечает за свою часть запроса. Так заполняя вкладку Таблицы и поля мы выбираем таблицы из которых запрос 1с будет получать данные и поля этих таблиц необходимые для решения конкретной задачи. Заполняя в кладку Условия мы накладываем условия на выбранные таблицы, для того чтобы выбрать из них только нужные нам данные и так далее.

Описание конструктора запросов на официальном сайте 1С 8: v8.1c.ru

Таблицы и поля; ; ; ; ; ; Вложенные запросы (в разработке).

Для того чтобы вызвать конструктор запросов 1с 8 в программном коде необходимо:

  • Создать новый запрос
Запрос = Новый Запрос;
  • Задать пустую строку текста запроса
Запрос.Текст = "";
  • Поставить курсор мышки между кавычками, нажать правую кнопку мыши. В открывшемся контекстном меню выбрать пункт Конструктор запроса и ответить Да на вопрос о создании нового запроса. Если текст запроса уже записан, то необходимо щелкнуть на любом месте внутри него и вызвать конструктор;

Рассмотрим на небольших примерах с возрастающей сложностью все основные вкладки конструктора запросов. Такой подход позволит начинающему программисту 1с более эффективно изучить конструктор и все его возможности. Для примеров будем использовать конфигурацию Бухгалтерия 3.0.

Урок №1. Конструктор запросов — простейший пример использования.

Задача: написать запрос к справочнику номенклатура, выбрать всю номенклатуру справочника.

Новые вкладки: Таблицы и поля.

Новые механизмы: просмотр и редактирование текста запроса при помощи кнопки «Запрос».

Для начала создания запроса создадим новый запрос и вызовем конструктор (как это делается написано несколькими абзацами выше). После этого откроется окно конструктора на вкладке Таблицы и поля.

Теоретическая часть урока №1

Вкладка Таблицы и поля состоит из трех разделов:

База данных . В данном разделе представлены все таблицы базы данных, которые можно использовать для построения запроса;

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

  • Либо дважды щелкнуть по таблице;
  • Либо воспользоваться кнопками «>» или «>>».

Над разделом Таблицы присутствует ряд кнопок. Про большинство из них будет подробнее рассказано в следующих уроках. А пока дам только краткие пояснения.

  • Создать вложенный запрос (красная линия). Предназначена для создания нового вложенного запроса;
  • Создать описание временной таблицы (желтая линия). Позволяет задать имя временной таблицы, которая расположена вне данного запроса, также можно использовать для передачи в запрос таблицы значений;
  • Изменить текущий элемент (зеленая линия). Позволяет перейти в выделенный вложенный запрос, временную таблицу или описание временной таблицы;
  • Удалить текущий элемент (голубая линия). Удаляет выделенную таблицу из выбранных таблиц;
  • Заменить таблицу (синяя линия). Открывает диалог замены выделенной таблицы. Полезно, если вы неверно выбрали виртуальную таблицу регистра, так как происходит позиционирование на текущей выбранной таблице в списке.
  • Параметры виртуальной таблицы (фиолетовая линия). Открывает параметры виртуальной таблицы регистра.

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

  • Либо дважды щелкнуть по полю;
  • Либо воспользоваться кнопками «>» или «>>»;
  • Также можно добавить новое поле самостоятельно, используя произвольное выражение из полей выбранных таблиц и функций языка запросов.

Над разделом Поля присутствует ряд кнопок. Про создание полей при помощи произвольных выражений будет подробнее рассказано в следующих уроках. А пока дам только краткие пояснения.

  • Добавить (зеленая линия). Предназначена для добавления нового поля при помощи редактора произвольных выражений;
  • Изменить текущий элемент (красная линия). Позволяет изменить выделенное поле при помощи редактора;
  • Удалить текущий (синяя линия). Удаляет выделенное поле из списка.

Практическая часть урока №1

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

Приступим к созданию запроса по номенклатуре:

  • Создадим новый запрос и откроем конструктор методом указанным в начале урока;
  • В разделе База данных , откроем ветку Справочники и найдем там справочник Номенклатура;
  • Выделим его и при помощи кнопки «>» перенесем в раздел Таблицы;
  • В разделе Таблицы раскроем справочник номенклатура при помощи значка «+»;
  • В раскрывшемся списке полей найдем поле Ссылка и перенесем его в раздел Поля при помощи кнопки «>»
  • Запрос по номенклатуре готов, нажимаем кнопку «ОК» в нижней части окна конструктора.

Рассмотрим, что такое вложенные запросы в и для чего они нужны.
Часто встречается ситуация, когда над таблицей необходимо проделать несколько последовательных действий. Достаточно показательным является пример, когда сначала надо , а потом уже на сгруппированную таблицу наложить некоторое условие, либо соединить с другой таблицей. В таких случаях на помощь и приходят вложенные запросы .

Вложенный запрос практически ничем не отличается от обычного запроса. Он заключается в скобки и в нем доступны почти все методы и функции языка запросов 1С. А для вышестоящего запроса доступны все поля вложенного запроса.
Структура самого примитивного вложенного запроса выглядит следующим образом

ВЫБРАТЬ ИЗ (ВЫБРАТЬ ИЗ) КАК ВложенныйЗапрос

Конечно же в таком виде использование вложенного запроса не имеет смысла, т.к. можно сразу выбрать необходимые поля без использования вложенности. Здесь все предельно упрощено для простоты понимания.

А теперь рассмотрим все вышесказанное на примере.
Пусть у нас есть таблица СотрудникиПодразделений:

И мы хотим выбрать из этой таблицы все подразделения, где работает более одного сотрудника.

ВЫБРАТЬ СотрудникиПодразделений.Подразделение КАК Подразделение, КОЛИЧЕСТВО(СотрудникиПодразделений.Сотрудник) КАК КоличествоСотрудников ИЗ СотрудникиПодразделений КАК СотрудникиПодразделений СГРУППИРОВАТЬ ПО СотрудникиПодразделений.Подразделение

Если выполнить этот запрос, то в результате получим следующую таблицу

Вторым шагом нам необходимо наложить на эту таблицу ограничение по количеству сотрудников. Для этого сделаем вышеприведенный запрос вложенным и в вышестоящем запросе пропишем соответствующее условие

ВЫБРАТЬ ВложенныйЗапрос.Подразделение КАК Подразделение ИЗ (ВЫБРАТЬ СотрудникиПодразделений.Подразделение КАК Подразделение, КОЛИЧЕСТВО(СотрудникиПодразделений.Сотрудник) КАК КоличествоСотрудников ИЗ СотрудникиПодразделений КАК СотрудникиПодразделений СГРУППИРОВАТЬ ПО СотрудникиПодразделений.Подразделение) КАК ВложенныйЗапрос ГДЕ ВложенныйЗапрос.КоличествоСотрудников > 1

Таким образом результат итогового запроса будет следующим

Справедливости ради стоит отметить, что тот же результат можно достигнуть с помощью функции ИМЕЮЩИЕ языка запросов 1С, а также с использованием временных таблиц.
На практике вы конечно же столкнетесь с более сложными вложенными запросами в которых может использоваться как , так и таблиц. А также может быть несколько уровней вложенности.

Решил внести свою лепту и описать те особенности языка, которые не были рассмотрены в приведенных выше статьях. Статья ориентирована на начинающих разработчиков.

1. Конструкция "ИЗ".

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

ВЫБРАТЬ Справочник.Банки.*

Выбирает все поля из справочника Банки. И является аналогичным запросу:

ВЫБРАТЬ Банки.* ИЗ Справочник.Банки КАК Банки

2. Упорядочивание данных по ссылочному полю

Когда нам необходимо упорядочить данные запроса по примитивным типам: "Строка", "Число", "Дата" и т.д., то все решается использованием конструкции "УПОРЯДОЧИТЬ ПО", если вам необходимо упорядочить данные по ссылочному полю? Ссылочное поле представляет из себя ссылку, уникальный идентификатор, т.е. грубо говоря некий произвольный набор символов и обычное упорядочивание может выдать не совсем ожидаемый результат. Для упорядочивания ссылочным полей используется конструкция "АВТОУПОРЯДОЧИВАНИЕ". Для этого необходимо сначала упорядочить данные непосредственно по ссылочному типу конструкцией "УПОРЯДОЧИТЬ ПО", а затем конструкция "АВТОУПОРЯДОЧИВАНИЕ".

В этом случае для документов упорядочивание будет происходить в порядке "Дата->Номер" , для справочников по "Основному представлению". Если упорядочивание происходит не по ссылочным полям, то использовать конструкцию "АВТОУПОРЯДОЧИВАНИЕ" не рекомендуется.

В некоторых случаях конструкция "АВТОУПОРЯДОЧИВАНИЕ" может замедлять процесс выборки. Аналогичным образом можно переписать без автоупорядочивания для документов:

3.Получение текстового представления ссылочного типа. Конструкция "ПРЕДСТАВЛЕНИЕ".

Когда вам необходимо вывести для показа поле ссылочного типа, например поле "Банк", которое является ссылкой на элемент справочника "Банки", то необходимо понимать, что при выводе этого поля автоматически выполнится подзапрос к справочнику "Банки", чтобы получить представление справочника. Это будет замедлять вывод данных. Для Того, чтобы этого избежать необходимо использовать конструкцию "ПРЕДСТАВЛЕНИЕ" в запросе, чтобы сразу получить представление объекта и уже его выводить для просмотра.

В система компоновки данных этот механизм используется по умолчанию, а вот при формировании макетов в ячейках следует указывать представление ссылочного поля, а например в расшифровку помещать саму ссылку.

4. Условие на выборку данных по шаблону.

Например, вам необходимо получить мобильные телефоны сотрудников вида (8 -123- 456-78-912). Для этого необходимо поставить такое условие в запросе:

ВЫБРАТЬ Сорудник.Наименование, Сорудник.Телефон КАК Телефон ИЗ Справочник.Сотрудники КАК Сотрудники ГДЕ Телефон ПОДОБНО "_-___-___-__-__"

Символ "_" является служебным и заменяет любой символ.

5. Одновременное использование итогов и группировок.


Итоги часто используются совместно с группировками, в таком случае агрегатные функции в итогах можно не указывать.

ВЫБРАТЬ ОказаниеУслуг.Организация КАК Организация, ОказаниеУслуг.Номенклатура КАК Номенклатура, СУММА(ОказаниеУслуг.СуммаДокумента) КАК СуммаДокумента ИЗ Документ.ОказаниеУслуг КАК ОказаниеУслуг СГРУППИРОВАТЬ ПО ОказаниеУслуг.Организация, ОказаниеУслуг.Номенклатура ИТОГИ ПО ОБЩИЕ, Организация, Номенклатура

В этом случае запрос вернет практически тоже самое что и такой запрос:

ВЫБРАТЬ ОказаниеУслуг.Организация КАК Организация, ОказаниеУслуг.Номенклатура КАК Номенклатура, ОказаниеУслуг.СуммаДокумента КАК СуммаДокумента ИЗ Документ.ОказаниеУслуг КАК ОказаниеУслуг ИТОГИ СУММА(СуммаДокумента) ПО ОБЩИЕ, Организация, Номенклатура

Только первый запрос свернет записи с одинаковой номенклатурой.

6. Разыменование полей.

Обращение к полям через точку называется операцией разыменования ссылочного поля. Например Оплата.Организация.АдминистративнаяЕдиница . В этом случае в ссылочном поле "Организация" документа "Оплата", ссылается на другую таблицу "Организации", в которой будет получено значение реквизита "АдминистративнаяЕдиница". Важно понимать, что при обращении к полям через точку платформа неявно создает подзапрос и соединяет эти таблицы.

Запрос:

Можно представить в виде:

ВЫБРАТЬ Оплата.Ссылка, Оплата.Организация, Оплата.Организация, Организации. АдминистративнаяЕдиница ИЗ Документ.Оплата КАК Оплата ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Организации КАК Организации ПО Оплата.Организация = Организации.Ссылка

При разыменовании ссылочных полей составного типа платформа пытается создать неявные соединения со всеми таблицами, которые входят в тип этого поля. В этом случае запрос будет неоптимален.Если четко известно, какого типа поле, необходимо ограничивать такие поля по типу конструкцией ВЫРАЗИТЬ() .

Например имеется регистр накопления "Нераспределенные оплаты", где регистратором могут выступать несколько документов. В этом случае неверно получать значения реквизитов регистратора таким образом:

ВЫБРАТЬ НераспределенныеОплаты.Регистратор.Дата, ..... ИЗ РегистрНакопления.НераспределеныеОплаты КАК НераспределенныеОплаты

следует ограничить тип составного поля регистратор:

ВЫБРАТЬ ВЫРАЗИТЬ(НераспределенныеОплаты.Регистратор КАК Документ.Оплата).Дата, ..... ИЗ РегистрНакопления.НераспределеныеОплаты КАК НераспределенныеОплаты

7. Конструкция "ГДЕ"

При левом соединении двух таблиц, когда вы накладываете условие "ГДЕ" на правую таблицу то мы получим результат аналогичный результату при внутреннем соединении таблиц.

Пример. Необходимо выбрать всех Клиентов из Справочника клиенты и для тех клиентов, у которых имеется документ оплата со значением реквизита "Организация" = &Организация вывести документ "Оплата", для тех у кого нет, не выводить.

Результат запроса вернет записи только для тех клиентов, у которых была оплата по организации в параметре, а других клиентов отсеет. Поэтому необходимо сначала получить все оплаты по "такой-то" организации во временной таблице, а потом уже соединять со справочником "Клиенты" левым соединением.

ВЫБРАТЬ Оплата.Ссылка КАК Оплата, Оплата.Пайщик КАК Клиент ПОМЕСТИТЬ тОплаты ИЗ Документ.Оплата КАК Оплата ГДЕ Оплата.Отделение = &Отделение; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ Клиенты.Ссылка КАК Клиент, ЕСТЬNULL(тОплаты.Оплата, "") КАК Оплата ИЗ Справочник.Клиенты КАК Клиенты ЛЕВОЕ СОЕДИНЕНИЕ тОплаты КАК тОплаты ПО Клиенты.Ссылка = тОплаты.Клиент

Можно обойти это условие и другим способом. необходимо наложить условие "ГДЕ" непосредственно в связи двух таблиц. Пример:

ВЫБРАТЬ Клиенты.Ссылка, Оплата.Ссылка ИЗ Справочник.УС_Абоненты КАК УС_Абоненты ЛЕВОЕ СОЕДИНЕНИЕ Документ.Оплата КАК Оплата ПО (Клиенты.Ссылка = Оплата.Клиент И Оплата.Клиент.Наименование ПОДОБНО "Сахарный Пакет") СГРУППИРОВАТЬ ПО Клиенты.Ссылка, Оплата.Ссылка

8. Соединения с Вложенными и Виртуальными таблицами

Вложенные запросы зачастую необходимы для выборки данных по какому-либо условию. Если же потом использовать их в соединении с другими таблицами то это может критически замедлить выполнение запроса.

Для примера нам необходимо для некоторых клиентов получить Сумму остатка на текущую дату.

ВЫБРАТЬ НераспределенныеОплатыОстатки.Клиент, НераспределенныеОплатыОстатки.СуммаОстаток ИЗ (ВЫБРАТЬ Клиенты.Ссылка КАК Ссылка ИЗ Справочник.Клиенты КАК Клиенты ГДЕ Клиенты.Ссылка В(&Клиенты)) КАК ВложенныйЗапрос ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.НераспределенныеОплаты.Остатки КАК НераспределенныеОплаты ПО ВложенныйЗапрос.Ссылка = НераспределенныеОплатыОстатки.Клиент

При выполнении такого запроса, вероятны ошибки оптимизатора СУБД при выборе плана, что приведет к неоптимальному выполнению запроса. При соединении двух таблиц оптимизатор СУБД выбирает алгоритм соединения таблиц исходя из количества записей в обеих таблицах. В случае наличия вложенного запроса, определить количество записей, которое вернет вложенный запрос крайне сложно. Поэтому вместо вложенных запросов всегда стоит использовать временные таблицы. Поэтому перепишем запрос.

ВЫБРАТЬ Клиенты.Ссылка КАК Ссылка ПОМЕСТИТЬ тКлиенты ИЗ Справочник.Клиенты КАК Клиенты ГДЕ
Клиенты.Ссылка В (&Клиенты) ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ тКлиенты.Ссылка, НераспределенныеОплатыОстатки.СуммаОстаток, ИЗ тКлиенты КАК тКлиенты ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.НераспределенныеОплаты.Остатки(, Клиент В (ВЫБРАТЬ тКлиенты.Ссылка ИЗ тКлиенты)) КАК НераспределенныеОплатыОстатки ПО тКлиенты.Ссылка = НераспределенныеОплатыОстатки.Клиенты

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

Виртуальные таблицы , позволяют получить практически готовые данные для большинства прикладных задач.(СрезПервых,СрезПоследних,Остатки,Обороты,ОстаткиИОбороты) Ключевое слово здесь виртуальные. Эти таблицы не являются физическими, а компонуются системой налету, т.е. при получении данных из виртуальных таблиц система собирает данные из итоговых таблиц регистров, компонует, группирует и выдает пользователю.

Т.е. при соединении с виртуальной таблицей происходит соединение с подзапросом. В этом случае оптимизатор СУБД может также выбрать неоптимальный план соединения. Если запрос формируется недостаточно быстро и в запросе испольуются соединения в виртуальными таблицами, то реклмендуется вынести обращение к виртуальным таблицам во временную таблицу, а затем в произвести соедининие между двумя временными таблицами. Перепишем предыдущий запрос.

ВЫБРАТЬ Клиенты.Ссылка КАК Ссылка ПОМЕСТИТЬ тКлиенты ИЗ Справочник.Клиенты КАК Клиенты ИНДЕКСИРОВАТЬ ПО Ссылка ГДЕ
Клиенты.Ссылка В (&Клиенты) ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ НераспределенныеОплаты.СуммаОстаток, НераспределенныеОплаты.Клиент КАК Клиент ПОМЕСТИТЬ тОстатки ИЗ РегистрНакопления.НераспределенныеОплаты.Остатки(, Клиент В (ВЫБРАТЬ тКлиенты.Ссылка ИЗ тКлиенты)) КАК НераспределенныеОплатыОстатки; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ тКлиенты.Ссылка, тОстатки.СуммаОстаток КАК СуммаОстаток ИЗ тКлиенты КАК тКлиенты ЛЕВОЕ СОЕДИНЕНИЕ тОстатки КАК тОстатки ПО тКлиенты.Ссылка = тОстатки.Клиент

9.Проверка результата выполнения запроса.

Результат выполнения запроса может быть пустым, для проверки на пустые значения следует использовать конструкцию:

РезЗапроса = Запрос.Выполнить(); Если резЗапроса.Пустой() Тогда Возврат; КонецЕсли;

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

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

Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Клиенты.Ссылка, | Клиенты.ДатаРождения |ИЗ | Справочник.Клиенты КАК Клиенты |ГДЕ | Клиенты.Ссылка = &Клиент"; Для Каждого Строка ИЗ ТаблицаКлиенты Цикл Запрос.УстановитьПараметр("Клиент", Клиент); РезультатЗапроса = Запрос.Выполнить().Выбрать(); КонецЦикла;

Это избавит систему от синтаксической проверки запроса в цикле.

11. Конструкция "ИМЕЮЩИЕ".

Конструкция, довольно редко встречающаяся в запросах. Позволяет накладывать условия на значения агрегатные функций (СУММА, МИНИМУМ, СРЕДНЕЕ и т.д.). Например, вам необходимо выбрать только тех клиентов, у которых сумма оплат в сентябре была больше 13 000 рублей. Если использовать условие "ГДЕ", то придется сначала создавать временную таблицу или вложенный запрос, там группировать записи по сумме оплаты и потом накладывать условие. Конструкция "ИМЕЮЩИЕ" поможет этого избежать.

ВЫБРАТЬ Оплата.Клиент, СУММА(Оплата.Сумма) КАК Сумма ИЗ Документ.Оплата КАК Оплата ГДЕ МЕСЯЦ(Оплата.Дата) = 9 СГРУППИРОВАТЬ ПО Оплата.Клиент ИМЕЮЩИЕ СУММА(Оплата.Сумма) > 13000

В конструкторе для этого достаточно перейти на вкладку "Условия", добавить новое условие и поставить галочку на "Произвольное". Далее просто написать Сумма(Оплата.Сумма) > 13000


12. Значение NULL

Я не буду описывать здесь принципы трехзначной логики в БД, есть множество статей на эту тему. Просто вкратце о том как NULL может повлиять на результат запроса. Значение NULL на самом деле не значение, а факт того, что значение не определено, неизвестно. Поэтому любые операции с NULL возвращают NULL, будь то сложение, вычитание, деление или сравнение. Значение NULL не может быть сравнимо со значением NULL, потому как мы не знаем, что именно сравнивать. Т.е. оба этих сравнения: NULL = NULL, NULL<>NULL - это не Истина или не Ложь, это неизвестно.

Давайте рассмотрим пример.

Нам необходимо для тех клиентов, у которых нет оплат, вывести поле "Признак" со значением "Нет оплат". Причем мы точно знаем, что такие клиенты у нас есть. И для того, чтобы отразить суть того, что писал выше сделаем это так.

ВЫБРАТЬ "Нет оплат" КАК Признак, NULL КАК Документ ПОМЕСТИТЬ тОплаты; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ Клиенты.Ссылка КАК Клиент, Оплата.Ссылка КАК Оплата ПОМЕСТИТЬ тКлиентОплата ИЗ Справочник.Клиенты КАК Клиенты ЛЕВОЕ СОЕДИНЕНИЕ Документ.Оплата КАК Оплата ПО Клиенты.Ссылка = Оплата.Пайщик; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ тКлиентОплата.Клиент ИЗ тКлиентОплата КАК тКлиентОплата ВНУТРЕННЕЕ СОЕДИНЕНИЕ тОплаты КАК тОплаты ПО тКлиентОплата.Оплата = тОплаты.Документ

Обратите внимание на вторую временную таблицу тКлиентОплата. Левым соединением я выбираю всех клиентов и все оплаты по этим клиентам. Для тех же клиентов у которых нет оплат в поле "Оплата" будет NULL . Следуя логике, в первой временной таблице "тОплаты" я обозначил 2 поля, одно из них NULL, второе строка "Не имеет оплат". В третьей таблице я соединяю внутренним соединением таблицы "тКлиентОплата" и "тОплаты" по полям "Оплата" и "Документ". Мы знаем, что в первой таблице поле "Документ" это NULL, и во второй таблице у тех, у кого нет оплат в поле "Оплата" тоже NULL. Что же вернет нам такое соединение? А ничего не вернет. Потому как сравнение NULL = NULL не принимает значение Истина.

Для того, чтобы запрос вернул нам ожидаемый результат, перепишем его:

ВЫБРАТЬ "Нет оплат" КАК Признак, ЗНАЧЕНИЕ(Документ.Оплата.ПустаяСсылка) КАК Документ ПОМЕСТИТЬ тОплаты; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ Клиенты.Ссылка КАК Клиент, ЕСТЬNULL(Оплата.Ссылка, ЗНАЧЕНИЕ(Документ.Оплата.ПустаяСсылка)) КАК Оплата ПОМЕСТИТЬ тКлиентОплата ИЗ Справочник.Клиенты КАК Клиенты ЛЕВОЕ СОЕДИНЕНИЕ Документ.Оплата КАК Оплата ПО Клиенты.Ссылка = Оплата.Пайщик; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ тКлиентОплата.Клиент ИЗ тКлиентОплата КАК тКлиентОплата ВНУТРЕННЕЕ СОЕДИНЕНИЕ тОплаты КАК тОплаты ПО тКлиентОплата.Оплата = тОплаты.Документ

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

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

13. Недокументированная особенность конструкции "ВЫБОР КОГДА...ТОГДА....КОНЕЦ".

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

ВЫБРАТЬ ВЫБОР КОГДА Пользователи.Наименование = "Вася Пупкин" ТОГДА "Наш любимый сотрудник" ИНАЧЕ "Не знаем такого" КОНЕЦ КАК Поле1 ИЗ Справочник.Пользователи КАК Пользователи

А что делать, если, к примеру, нам надо получить название месяца в запросе? Писать огромную конструкцию в запросе некрасиво и долго, поэтому нас может выручить такая форма записи выше:

ВЫБОР МЕСЯЦ(УС_РасчетПотребления_ГрафикОбороты.ПериодРасчета) КОГДА 1 ТОГДА "Январь" КОГДА 2 ТОГДА "Февраль" КОГДА 3 ТОГДА "Март" КОГДА 4 ТОГДА "Апрель" КОГДА 5 ТОГДА "Май" КОГДА 6 ТОГДА "Июнь" КОГДА 7 ТОГДА "Июль" КОГДА 8 ТОГДА "Август" КОГДА 9 ТОГДА "Сентябрь" КОГДА 10 ТОГДА "Октябрь" КОГДА 11 ТОГДА "Ноябрь" КОГДА 12 ТОГДА "Декабрь" КОНЕЦ КАК Месяц

Теперь конструкция выглядит не такой громоздкой и легко воспринимается.

14. Пакетное выполнение запроса.


Для того, чтобы не плодить запросы, можно создать один большой запрос, разбить его на пакеты и работать уже с ним.
Например, мне нужно получить из справочника "Пользователи" поля: "ДатаРождения" и доступные роли для каждого пользователя. в выгрузить это в разные табличные части на форме. Конечно можно сделать это в одном запросе, тогда придется перебирать записи или сворачивать, а можно так:

ВЫБРАТЬ Пользователи.Ссылка КАК ФИО, Пользователи.ДатаРождения, Пользователи.Роль ПОМЕСТИТЬ втПользователи ИЗ Справочник.Пользователи КАК Пользователи; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ втПользователи.ФИО, втПользователи.ДатаРождения ИЗ втПользователи КАК втПользователи СГРУППИРОВАТЬ ПО втПользователи.ФИО, втПользователи.ДатаРождения; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ втПользователи.ФИО, втПользователи.Роль ИЗ втПользователи КАК втПользователи СГРУППИРОВАТЬ ПО втПользователи.ФИО, втПользователи.ДатаРождения

тПакет = Запрос.ВыполнитьПакет();

ТП_ДатыРождения = тПакет.Выгрузить();
ТП_Роли = тПакет.Выгрузить();

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

15. Условия в пакетном запросе

Например, у нас есть пакетный запрос, где сначало мы получаем поля: "Наименование, ДатаРождения, Код" из справочника "Пользователи" и хотим из справочника "ФизЛица" получить записи с условием по этим полям.

ВЫБРАТЬ Пользователи.ФизЛицо.Наименование КАК Наименование, Пользователи.ФизЛицо.ДатаРождения КАК ДатаРождения, Пользователи.ФизЛицо.Код КАК Код ПОМЕСТИТЬ втПользователи ИЗ Справочник.Пользователи КАК Пользователи; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ ФизическиеЛица.Ссылка КАК ФизЛицо ИЗ Справочник.ФизическиеЛица КАК ФизическиеЛица

Можно накложить условия таким образом:

ГДЕ ФизическиеЛица.Код В (ВЫБРАТЬ втПользователи.Код ИЗ втПользователи) И ФизическиеЛица.Наименование В (ВЫБРАТЬ втПользователи.Код ИЗ втПользователи) И ФизическиеЛица.ДатаРождения В (ВЫБРАТЬ втПользователи.ДатаРождения ИЗ втПользователи)

А Можно и так:

ГДЕ (ФизическиеЛица.Код, ФизическиеЛица.Наименование, ФизическиеЛица.ДатаРождения) В (ВЫБРАТЬ втПользователи.Код, втПользователи.Наименование, втПользователи.ДатаРождения ИЗ втПользователи)

Причем обязателено соблюдать порядок.

16. Вызов конструктора запросов для "условия" в пакетном запросе

Когда необходимо наложить условие, как в примере выше, можно забыть как то или иное поле называется в виртуальной таблице.
Например надо наложить условие на поле "ДатаРождения", а в виртуальной таблице это поле называется "ДатаРожденияДебитора", и если вы забыли название, то придется выходить из редактирования условия без сохранения и смотреть название поля. Для того, чтобы избежать этого можно воспользоватьтся следующим приемом.

Необходимо после Конструкции "В" поставить скобки и между скобками оставить пустое место(пробел), выделить это место и вызвать контруктор запросов. Контруктору будут доступны все таблицы пакетного запроса. Прием работает как на виртуальных таблицах регистров, так и для вкладки "Условия". В последнем случае необходимо поставить галочку "П(произволное условие)" и войти в режим редактирования "F4".

Запросов зачастую выдумывал на ходу и они служат просто для отображения "приемов", которые я рассматривал.

Хотел рассмотреть использование индексов в запросах, но больно обширная тема. Вынесу в отдельную статью, либо позже добавлю здесь.

upd1. Пункты 11,12
upd2. Пункты 13,14,15,16

Используемая литература:
Язык запросов "1С:Предприятия 8" - Е.Ю. Хрусталева
Профессиональная разработка в системе 1С:Предприятие 8".

просмотров