Вложенные запросы. Сложные SQL запросы

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

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

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

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

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

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

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

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

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

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

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

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

Часто при выборке данных бывает необходимо объединить информацию из нескольких связанных таблиц. Сделать это можно посредством вложенных запросов, либо при помощи соединения с помощью SQL.

Вложенные запросы

В рамках нашего примера, допустим, что нам понадобилось узнать имена узлов, которые посещали сайт www.dom2.ru. Требуемую информацию можно получить запросом:

SELECT hst_name FROM hosts WHERE hst_pcode IN (SELECT vis_hstcode FROM visits, sites WHERE (sit_pcode = vis_sitcode) AND (sit_name LIKE "www.dom2.ru"));

Рассмотрим этот запрос более пристально. Первый оператор SELECT нужен для выборки имен узлов. Чтобы выбрать требуемые нам имена, в запросе указана секция WHERE, в которой первичный ключ таблицы «Узлы» (hst_pcode) проверяется на принадлежность множеству (оператор IN). Судя по всему, множество для проверки на принадлежность должен вернуть второй оператор SELECT, находящийся в скобках. Рассмотрим его отдельно:

SELECT vis_hstcode FROM visits, sites WHERE (sit_pcode = vis_sitcode) AND (sit_name LIKE "www.dom2.ru")

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

Соединение с помощью SQL

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

Внутреннее соединение

Рассмотрим пример:

SELECT hst_name, sit_name, vis_timestamp FROM hosts, visits, sites WHERE (hst_pcode = vis_hstcode) AND (vis_sitcode = sit_pcode)

Данный запрос вернет следующие данные

hst_name sit_name vis_timestamp
ws1 www.dom2.ru 2012-08-01 07:59:58.209028
ws1 www.vkontakte.ru 2012-08-01 08:00:10.315083
1-1 www.vkontakte.ru 2012-08-01 08:00:20.025087
1-2 www.opennet.ru 2012-08-01 08:00:26.260159

В этом примере из трех таблиц (hosts, visits, sites) выбирается по одному полю и создается новая таблица, в которой будут собраны имена узлов, посещаемых сайтов и время посещений. Представление соединяемых данных регламентируется условиями в операторе WHERE. Видно, что имеется два условия, которые соединяют три таблицы. Поскольку в таблице посещений (visits) вместо имени узла и наименования сайта указаны их идентификаторы, при соединении таблиц мы добавляем условие, чтобы связать по идентификаторам данные и тогда все встанет на свои места. Если по каким-то причинам, вопреки ссылочной целостности в таблице посещений будут находиться записи с идентификатором несуществующего узла или сайта, они не появятся в результирующем наборе данных запроса в этом примере.

Указанный выше пример немного упрощен и из-за немного упрощения теряется наглядность. Более наглядная форма запроса, соединяющего несколько таблиц и возвращающего тот же самый набор данных будет иметь вид

SELECT hst_name, sit_name, vis_timestamp FROM hosts JOIN visits ON (hst_pcode = vis_hstcode) JOIN sites ON (vis_sitcode = sit_pcode);

В запросе присутствует два оператора JOIN… ON. Поскольку «Join» можно перевести как «соединение» или «объединение», этот пример более красноречив. Если попытаться перевести текст SQL-запроса на русский, получится что-то вроде

ВЫБРАТЬ (поля) hst_name, sit_name, vis_timestamp ИЗ (таблицы) hosts СОЕДИНИВ (с таблицей) visits ПО (условию) (hst_pcode = vis_hstcode) СОЕДИНИВ (с таблицей) sites ПО (условию) (vis_sitcode = sit_pcode);

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

Внешнее соединение

Использованные выше способы соединения таблиц называются внутреннее соединение (inner join). У такого способа соединения есть недостатки. Например, если у нас не было посещений на один из сайтов, либо один из узлов не совершил ни одного посещения, то в результирующем наборе данных сайт или узел будут отсутствовать. В примере выше видно, что сайт www.yandex.ru отсутствует в данных, равно как и узел 1-3.Иногда это нежелательно и в таких случаях используют внешнее соединение (outer join). Внешнее соединение может быть левым (left join) и правым (right join). Сторона соединения (левая или правая) соответствует таблице, данные из которой будут выбираться полностью. Таким образом, при использовании LEFT JOIN, данные из таблицы слева от оператора JOIN будут выбираться полностью. Закрепим это примером. Допустим, надо выбрать ВСЕ узлы и связанные с ними посещения. Сделать это можно посредством запроса

SELECT hst_name, vis_timestamp FROM hosts LEFT JOIN visits ON (hst_pcode = vis_hstcode);

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

hst_name vis_timestamp
ws1 2012-08-01 07:59:58.209028
ws1 2012-08-01 08:00:10.315083
1-1 2012-08-01 08:00:20.025087
1-2 2012-08-01 08:00:26.260159
1-3

Видно, что узлу 1-3 не соответствует ни одно посещение, но он все равно в списке. Аналогичным образом работает RIGHT JOIN. Запрос, который вернет тот же набор данных можно записать с использованием RIGHT JOIN:

SELECT hst_name, vis_timestamp FROM visits RIGHT JOIN hosts ON (hst_pcode = vis_hstcode);

В этом случае, надо сменить LEFT JOIN на RIGHT JOIN и поменять местами таблицы visits и hosts в запросе.

Использование UNION

Иногда бывает нужно получить два списка записей из таблиц в виде одного. Для этой цели может быть использовано ключевое слово UNION, которое позволяет объединить результирующие наборы данных двух запросов в один набор данных. Допустим, надо получить некоторый список, в котором были бы узлы сети и имена сайтов. Таблицы разные, соответственно и запросы будут разными. Как объединить все в один набор данных? Легко, но есть определенные требования к такому «склеиванию» запросов:

§ запросы должны содержать одинаковое число полей;

§ типы данных полей объединяемых запросов так же должны совпадать.

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

SELECT hst_name AS name FROM hosts UNIONSELECT sit_name AS name FROM sites;

При таком подходе возможны проблемы с сортировкой записей. Чтобы список сайтов шел после списка узлов, можно умышленно добавить целочисленное поле, где указывать номер, который будет участвовать в сортировке. Например

SELECT 1 AS level, hst_name AS name FROM hosts UNIONSELECT 2 AS level, sit_name AS name FROM sitesORDER BY level, name;

Условия EXISTS и NOT EXISTS

Иногда бывает необходимо выбрать из таблицы записи, которым соответствуют (или не соответствуют) записи в других таблицах. Допустим, что нам нужен список сайтов, на которые не было посещений. Получить такой список можно запросом

SELECT sit_name FROM sites WHERE ((SELECT COUNT(*) FROM visits WHERE vis_sitcode = sit_pcode) = 0);

Для нашего примера, список будет коротким:

sit_name
www.yandex.ru

Запрос работает следующим образом:

§ из таблицы sites выбирается код сайта и его наименование;

§ код сайта передается во вложенный запрос, который считает записи с этим кодом в таблице visits;

§ функция COUNT(*) сосчитает записи и вернет их количество, который будет передано в условие;

§ при истинности условия (количество записей равно 0) имя сайта добавляется в список.

Если некоторым этот запрос покажется непонятным, то можно добиться тех же результатов посредством запроса с использованием NOT EXISTS:

SELECT sit_name FROM sites WHERE NOT EXISTS (SELECT vis_pcode FROM visits WHERE vis_sitcode = sit_pcode);

Выражение NOT EXISTS (на мой взгляд) вносит дополнительную ясность и более доступно для понимания. Аналогично работает выражение EXISTS, которое проверяет наличие записей.

Представления (VIEW)

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

CREATE VIEW show_dom2 ASSELECT hst_name FROM hosts WHERE hst_pcode IN (SELECT vis_hstcode FROM visits, sites WHERE (sit_pcode = vis_sitcode) AND (sit_name LIKE "www.dom2.ru"));

Собственно, всё. Внимательный наблюдатель, наверное, заметил, что по-сути, можно взять запрос и в самом начале добавить слова «CREATE VIEW <имя> AS». Именно по такому принципу можно рекомендовать создание представлений. Создайте запрос, убедитесь в его работоспособности и потом допишите все необходимое, чтобы сохранить этот запрос на сервере как представление. Единственный недостаток использования представлений заключается в том, что некоторые особо сложные приемы написания запросов могут не работать в представлениях. К сожалению, в документации по postgreSQL очень мало сведений о представлениях и однозначно узнать, что можно использовать, а что нет вы сможете методом проб и ошибок. Сохранив запрос на сервере как представление, вы сможете выполнить его сколько угодно раз, запросом типа

SELECT * FROM show_dom2;

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

DROP VIEW show_dom2;

Заключение

данные отчет запрос заказ

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

ЗАКЛЮЧЕНИЕ


СПИСОК ЛИТЕРАТУРЫ


ПРИЛОЖЕНИЕ А


ПРИЛОЖЕНИЕ Б


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

Подзапросы

Язык SQL разрешает использовать в других операторах языка DML подзапросы , которые являются внутренними запросами, определяемыми оператором SELECT .

Подзапрос - очень мощное средство языка SQL. Он позволяет строить сложные иерархии запросов, многократно выполняемые в процессе построения результирующего набора или выполнения одного из операторов изменения данных (DELETE , INSERT , UPDATE ).

Условно подзапросы иногда подразделяют на три типа, каждый из которых является сужением предыдущего:

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

Подзапрос позволяет решать следующие задачи:

  • определять набор строк, добавляемый в таблицу на одно выполнение оператора INSERT ;
  • определять данные, включаемые в представление, создаваемое оператором CREATE VIEW ;
  • определять значения, модифицируемые оператором UPDATE ;
  • указывать одно или несколько значений во фразах WHERE и HAVING оператора SELECT ;
  • определять во фразе FROM таблицу как результат выполнения подзапроса ;
  • применять коррелированные подзапросы . Подзапрос называется коррелированным, если запрос, содержащийся в предикате, имеет ссылку на значение из таблицы (внешней к данному запросу), которая проверяется посредством данного предиката.

Hекоторые СУБД (например, СУБД Oracle) позволяют на основе подзапроса создавать новые таблицы с помощью оператора CREATE TABLE .

Простым примером использования подзапроса может служить следующий оператор:

В данном операторе подзапрос всегда должен возвращать единственное значение, которое будет проверяться в предикате. Если подзапрос вернет более одного значения, то СУБД выдаст сообщение об ошибке выполнения SQL-оператора.

В случае если подзапрос не выберет ни одной строки, то предикат будет равен UNKNOWN , что большинством СУБД интерпретируется как FALSE .

Стандарт определяет запись предиката в форме "значение оператор подзапрос ". Однако некоторые СУБД также позволяют записывать предикат в форме, указывающей подзапрос слева от оператора сравнения.

Например:

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

Например:

Если результатом подзапроса становится группа строк (это случается всегда, когда условие не гарантирует уникальности значения проверяемого предикатом внутреннего запроса), то следует использовать оператор IN , осуществляющий выбор одного значения из указываемого множества.

Например:

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

Однако применение оператора IN имеет и некоторые смысловые недостатки: в запросе четко не определяется, сколько строк должны быть результатом выполнения запроса. При построении отношений для реальной модели данных это может приводить к некоторой неоднозначности и зависимости от самих данных. В противном случае, если модель данных предполагает в качестве постоянного результата подзапроса наличие только одной строки и, соответственно, использует оператор сравнения = , а структура данных позволяет ввод значений, когда в результате подзапроса будет более одной строки, то при использовании такого SQL-оператора в какой-то момент времени может проявиться ошибка.

Если в запросе участвуют более двух таблиц, то для большей наглядности имена полей иногда квалифицируют именами таблиц, указывая их через точку. Стандарт позволяет не квалифицировать имя поля именем таблицы в том случае, если не возникает неоднозначности (поле сначала ищется в таблице, указанной фразой FROM текущего запроса, затем внешнего запроса и т.д.).

Очень часто вместо записи оператора SELECT с использованием подзапроса можно применять соединения. Однако на практике большинство СУБД подзапросы выполняют более эффективно. Тем не менее, при проектировании комплекса программ с критичными требованиями по быстродействию, разработчик должен проанализировать план выполнения SQL-оператора для конкретной СУБД.

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

Подзапрос может быть указан как в предикате, определяемом фразой WHERE , так и в предикате по группам, определяемом фразой HAVING .

Например:

Коррелированные подзапросы

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

Например:

В данном случае для каждой строки таблицы tbl1 будет проверяться условие, что значение поля f2 совпадает со значением строки таблицы tbl2 , где значение поля f3 равно значению поля f3 внешней таблицы (tbl1 ). Это простейший пример коррелированного подзапроса .

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

Например:

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

Например:

Построение предиката для подзапроса, возвращающего несколько строк

Если в предикате надо сравнить значение с некоторым множеством, то, как было показано выше, можно использовать оператор IN .

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

Например:

Этот запрос будет формировать не пустой результирующий набор только в том случае, если в какое-либо значение столбца f4 таблицы была занесена дата, например: "10/11/2003".

Преимущество применения оператора EXISTS с результатами подзапроса состоит в том, что подзапрос может возвращать как множество строк, так и множество столбцов.

При коррелированном подзапросе оператор EXISTS будет вычисляться каждый раз для каждой строки внешнего запроса.

В стандарте SQL-92 не предусмотрено использование в подзапросах , к которым применяется оператор EXISTS агрегирующих функций. Однако некоторые СУБД позволяют такой вид подзапросов .

Для использования результата подзапроса в предикате также применяются операторы ANY и ALL , которые были подробно рассмотрены в предыдущих лекциях.

Приведем пример использования оператора ANY :

Данный оператор определяет, что в результирующий набор будут включены все строки, значение столбца f3 которых присутствует в таблице tbl2 .

Применение подзапросов в операторах изменения данных

К операторам языка DML, кроме оператора SELECT , относятся операторы, позволяющие изменять данные в таблицах. Это оператор INSERT , выполняющий добавление одной или нескольких строк в таблицу, оператор DELETE , удаляющий из таблицы одну или несколько строк, и оператор UPDATE , изменяющий значения столбцов таблицы.

Оператор INSERT

Оператор INSERT

INSERT INTO table_name [ (field .,:) ] { VALUES (value .,:) } | subquery | {DEFAULT VALUES};

Оператор INSERT может добавлять в таблицу как одну, так и несколько строк. Список полей (field .,:) указывает имена полей и порядок занесения в них значений из списка значений, определяемого фразой VALUES , или как результат выполнения подзапроса .

Список, определяемый фразой VALUES , называется конструктором значений таблицы и указывается в круглых скобках через запятую.

Если список полей (field .,:) опущен, то порядок занесения значений будет соответствовать порядку столбцов, указанному в операторе CREATE TABLE при создании данной таблицы.

Если для столбцов, на которые установлено ограничение NOT NULL , не указано добавляемых данных, то СУБД инициирует ошибку выполнения SQL-оператора.

Следующий оператор INSERT демонстрирует копирование строк таблицы tbl2 , выполняемое на основе подзапроса :

INSERT INTO tbl1(f1,f2,f3) (SELECT f1,f2,f3 FROM tbl2);

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

Оператор DELETE

Оператор DELETE в стандарте SQL-92 имеет следующее формальное описание:

Оператор DELETE используется для удаления из таблицы строк, указанных условием во фразе WHERE (поисковое удаление, searched deletion) или WHERE CURRENT OF (позиционное удаление, positioned deletion).

Позиционное удаление, определяемое фразой WHERE CURRENT OF , удаляя строки из курсора, соответственно удаляет их и из той таблицы базы данных, на базе которой был построен этот курсор.

Если оператор DELETE применяется к какому-либо представлению, то данные удаляются также из созданной на основе последнего таблицы базы данных.

Никогда нельзя забывать, что если фраза WHERE будет отсутствовать или предикат во фразе WHERE будет всегда принимать значение TRUE , то оператор DELETE удалит из таблицы все строки.

Оператор UPDATE

Оператор UPDATE в стандарте SQL-92 имеет следующее формальное описание:

Оператор UPDATE применяется для внесения изменений в данные таблиц.

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

При вычислении значений столбцов можно применять условное выражение CASE и выражение CAST для приведения типов.

Например:

Условное выражение CASE

Условное выражение CASE позволяет выбрать одно из нескольких значений на основании указываемого условия.

Условное выражение CASE имеет следующее формальное описание:

{ CASE { expr WHEN expr THEN { expr | NULL }} | { WHEN expr THEN { expr | NULL }} [ ELSE { expr | NULL } ] END} | { NULLIF {expr1,expr2) } | {COALESCE (expr .,:) }

Условное выражение CASE может быть записано, соответственно, в четырех формах:

  • CASE с выражениями. Например:

    SELECT f1, CASE f3 WHEN "abc" THEN "1_abc" END FROM tbl1;

  • CASE с предикатами. Например:

    SELECT f1, CASE WHEN f3= "abc" THEN "1_abc" ELSE f3 END FROM tbl1;

  • NULLIF - если выражения, указанные в скобках, не совпадают, то выбирается первое из этих значений, в противном случае устанавливается значение NULL . Например:
  • COALESCE - выбирается первое значение в списке, не равное NULL . Например:

    INSERT INTO tbl1(f1,f2) VALUES (1+ COALESCE(SELECT MAX(f1) FROM tbl1, 0), 100);

Для успешного выполнения оператора UPDATE требуется ряд условий, включающий следующие:

  • наличие соответствующих привилегий;
  • для представления требуется определение его как изменяемого;
  • при изменении представлений применяются ограничения WITH CHECK OPTION или WITH CASCADED CHECK OPTION , установленные при создании этого представления;
  • в транзакциях "только чтение" изменение доступно только для временных таблиц;
  • выражения, используемые для определения значений, не могут содержать подзапросы с агрегирующими функциями;
  • для обновляемого курсора, указанного фразой FOR UPDATE , каждый изменяемый столбец также должен быть определен как FOR UPDATE ;
  • в курсоре с фразой ORDER BY нельзя выполнять изменение столбцов, указанных в этой фразе.

Вложенный запрос относится к специальным объектам в программе 1С. К его функционалу прибегают, если требуется сформировать и выполнить специальные виды запросов к таблицам базы данных (БД) в программе. Для получения результата по запросу сначала необходимо корректное составление текста запроса, который будет аккумулировать актуальную информацию об источниках для получения данных. Это могут быть таблицы, специальные поля, уникальные группировки.

Современный язык запросов для программы 1С

Вложенные запросы пишутся с применением языка, который имеет свои особенности и в тоже время похож на другие специальные языки SQL, к примеру, по своему синтаксису. Главные отличительные черты языка запросов в 1С такие:

  • Разыменование ссылочных полей;
  • Возможности нетипичных запросов;
  • Упорядочивание по примитивным типам;
  • Использование конструкции «Представление»;
  • Выборка данных по шаблону;
  • Совместное использование группировок и итогов;
  • Конструкция с условием «Где».

Есть и другие отличительные особенности языка запросов в 1С, которые позволяют ему быть эффективным.

Что нужно знать о вложенных запросах и языке запросов?

Профессиональное изучение конструкции языка запроса позволяет не только понять, для чего предназначен язык запросов , но и научится представлять совокупность объектов базы в формате 2-х мерных таблиц, обрабатывать консоль запросов, создавать файлы для хранения списков запросов, познакомиться со специфическими полями таблиц, имеющих ссылочный тип. И всё это будут только начальные знания о системе вложенных запросов в 1С. Важно освоить и групповые операции, относящиеся к языку запросов, изучить, как делать корректную выборку по нескольким источникам данных.

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

Рассмотрим один из вариантов вложенного запроса на основе объединения запросов. Предположим, есть документы по приходу и расходу, при этом одно и то же юридическое лицо выступает и как продавец, и как покупатель. Нам нужно узнать, общий долг по контрагенту. Для этого используем эффективную конструкцию «ОБЪЕДИНИТЬ ВСЕ».

Таблица «ПРИХОД»

Таблица «РАСХОД»

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

Результат действия:

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

Тогда результатом отчёта будет:

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

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

Существуют определённые требования, которых необходимо придерживаться, выполняя объединение двух запросов. Прежде всего, это касается количества полей. Необходимо, чтобы их число было идентичным. К примеру, если бы в таблице данных «Расход» была указана Скидка, а в данных по Приходу такого элемента не было бы, то следует прибегнуть к следующей конструкции:

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

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

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



Есть вопросы?

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: