Вложенные запросы. Примеры

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

Подзапросы

Язык 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,
ВложенныйЗапрос.Поле2
ИЗ
(ВЫБРАТЬ
Таблица1.Поле1,
Таблица1.Поле2
ИЗ ТаблицаДанных КАК Таблица1) КАК ВложенныйЗапрос"
;

В том числе в соединениях:

Запрос. Текст= "ВЫБРАТЬ
ВложенныйЗапрос.Наименование,

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

И в условиях запроса со сравнением В или В ИЕРАРХИИ:

Запрос. Текст= "ВЫБРАТЬ
ЧерныйСписокСрезПоследних.Состояние
ИЗ
РегистрСведений.ЧерныйСписок.СрезПоследних КАК ЧерныйСписокСрезПоследних
ГДЕ
ЧерныйСписокСрезПоследних.Котрагент В
(ВЫБРАТЬ ПЕРВЫЕ 10
Контрагенты.Ссылка
ИЗ
Справочник.Контрагенты КАК Контрагенты)"
;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Подзапрос - это запрос, содержащийся в выражении ключевого слова WHERE другого запроса с целью дополнительных ограничений на выводимые данные. Подзапросы называют также вложенными запросами. Их используют для наложения условий на выводимые данные. Подзапросы могут использоваться с операторами SELECT, INSERT, UPDATE или DELETE.

В некоторых случаях подзапрос можно использовать вместо связывания таблиц, тем самым связывая данные таблиц неявно. При использовании в запросе подзапроса сначала выполняется подзапрос, а только потом - содержащий его запрос, причем с учетом условий выполнения подзапроса. Подзапрос можно использовать либо в выражении ключевого слова WHERE, либо в выражении ключевого слова HAVING главного запроса. Логические операции и операции сравнения типа =, >, <, о, IN, NOT IN, AND, OR и т п. можно использовать в подзапросе. Все, что применимо к обычному запросу, применимо и к подзапросу.

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

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

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

Ключевое слово ORDER BY использовать в подзапросе нельзя, хотя в главном запросе ORDER BY использоваться может. Вместо ORDER BY в подзапросе можно использовать GROUP BY.

Подзапрос, возвращающий несколько строк данных, можно использовать только в операторах, допускающих множество значений, например в IN.

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

SELECT имя_столбиа FROM таблица WHERE имя_столбца = (SELECT имя__столбца FROM таблица WHERE условия);

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

Пример. Пусть требуется определить количество предметов обучения с оценкой, превышающей среднее значение оценки студента с идентификатором 301:

SELECT COUNT (DISTINCT subj_id), mark FROM exam_marks GROUP BY mark HAVING mark > (SELECT AVG(mark) FROM exam_marks WHERE stud_id=301);

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

Связанные подзапросы допускаются во многих реализациях SQL. При использовании подзапросов во внутреннем запросе можно ссылаться на таблицу, имя которой указано в предложении FROM внешнего запроса. Такие подзапросы называются связанными. Связанный подзапрос выполняется по одному разу для каждой строки таблицы основного запроса, а именно:



Выбирается строка из таблицы, имя которой указано во внешнем запросе;

Выполняется подзапрос, и полученное в результате его выполнения значение применяется для анализа этой строки в условии WHERE внешнего запроса;

По результату оценки этого условия принимается решение о включении / невключении строки в состав выходных данных;

Процедура повторяется для следующей строки таблицы внешнего запроса.

Предложение GROUP BY позволяет группировать выводимые SELECT–запросом записи по значению некоторого поля. Использование предложения HAVING позволяет при выводе осуществлять фильтрацию таких групп. Предикат предложения HAVING оценивается не для каждой строки результата, а для каждой группы выходных записей, сформированной предложением GROUP BY внешнего запроса.

SELECT exam_date, SUM(mark) FROM exam_marks a GROUP BY exam_date

HAVING 10< (SELECT COUNT(mark) FROM exam_marks b

WHERE a.exam_date=b.exam_date);

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

Резюме: подзапрос представляет собой запрос, выполняемый в рамках другого запроса для задания дополнительных условий на выводимые данные. Подзапрос можно использовать в выражениях ключевых слов WHERE и HAVING. Синтаксис подзапросов практически не отличается от синтаксиса обычного запроса, имеются лишь небольшие ограничения. Одним из таких ограничений является запрет на использование в подзапросах ключевого слова ORDER BY, однако, вместо него можно использовать GROUP BY, чем достигается практически тот же эффект. Подзапросы используются для размещения в запросах условий, точные данные для которых не известны, тем самым расширяя возможности и гибкость SQL.

  • 4.Основные понятия в концептуальном проектировании реляционных баз данных (сущность, атрибуты, отношения). Элементы реляционной модели.
  • Зависимости между атрибутами
  • 5.Целостность данных и ее виды. Нарушения целостности (аномалии).
  • 6.Функциональные связи атрибутов и нормализация таблиц. Основные нормальные формы (нф). Примеры нф.
  • 7.Использование er–моделирования в концептуальном проектировании бд. Диаграммы er- экземпляров и er-типов.
  • 8.Преобразование концептуальной модели в реляционную. Основные этапы и правила формирования отношений (пример).
  • 9.Структура и основные технические характеристики субд access 200*.Возможности проектирования персональных и сетевых приложений.
  • 10.Конструирование таблиц в ms access хр.Свойства полей. Определение типа данных, ключей, индексов.
  • 11.Связывание таблиц в субд access. Логическая схема и обеспечение ссылочной целостности данных.
  • 12.Средства реализации запросов в субд access. Виды запросов.
  • 5.2.3 Запрос к связанным таблицам
  • 5.2.4 Запросы удаления
  • 13.Реализация запросов с групповыми операциями и вычисляемыми полями. Примеры.
  • 14.Реализация запросов на модификацию и на создание таблицы.
  • 15.Стандарты современных реализаций языка sql. Основные разделы и их наполнение в sql-Jet.
  • 16.Общий формат select-инструкции (запроса на выборку). Пример реализации.
  • 17.Пример qbe- и sql–реализации перекрестного запроса.
  • 18.Создание интерфейса приложения в субд access. Работа в конструкторе форм. Разделы, элементы управления, свойства.
  • 19.Создание вложенных sql-запросов. Пример реализации.
  • 20.Программы сервиса субд access.
  • 21.Защита и администрирование бд средствами субд access.
  • 22.Использование макросов, отчетов и страниц доступа к данным в приложениях ms access хр.
  • 23.Система программирования Matlab: общая характеристика. Пакеты расширения и специализированные приложения: назначения и возможности. Подсистема Simulink.
  • 24.Структуры данных и основные структуры управления в системе программирования matlab
  • 25.Графические средства системы matlab. Работа с инструментом lti-Viewer графического анализа линейных систем управления.
  • 26.Этапы построения модели в подсистеме Simulink. Элементы технологии визуально-блочного моделирования. Настройка параметров моделирования и параметров блоков.
  • 27.Общее описание блоков библиотеки simulink.
  • 28.Реализация принципа иерархии в Simulink – моделях посредством блоков портов и подсистем. Маскирование подсистем.
  • 29.Компоненты виртуального прибора и их сборка в приложение в среде LabView. Основные элементы управления и индикаторы LabView и их соединение на блок-диаграмме.
  • 19.Создание вложенных sql-запросов. Пример реализации.

    С помощью SQL можно вкладывать запросы внутрь друг друга. Обычно внутренний запрос генерирует значение, которое проверяется в предикате внешнего запроса (в предложении WHERE или HAVING), определяющего, верно оно или нет. Совместно с подзапросом можно использовать предикат EXISTS, который возвращает истину, если вывод подзапроса не пуст.

    В сочетании с другими возможностями оператора выбора, такими как группировка, подзапрос представляет собой мощное средство для достижения нужного результата. В части FROM оператора SELECT допустимо применять синонимы к именам таблицы, если при формировании запроса нам требуется более чем один экземпляр некоторого отношения. Синонимы задаются с использованием ключевого слова AS, которое может быть вообще опущено. Поэтому часть FROM может выглядеть следующим образом:

    FROM Rl AS A, Rl AS В

    FROM Rl A. Rl В:

    оба выражения эквивалентны и рассматриваются как применения оператора SELECT к двум экземплярам таблицы R1.

    Например, покажем, как выглядят на SQL некоторые запросы к БД «Сессия»:

     Список тех, кто сдал все положенные экзамены.

    WHERE Оценка > 2

    HAVING COUNT(*) = (SELECT COUNT(*)

    WHERE R2.Группа=R3.Группа AND ФИОа.ФИО)

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

     Список тех, кто должен был сдавать экзамен по БД, но пока еще не сдавал.

    SЕLЕСТ ФИО

    WHERE R2.Fpynna=R3.Группа AND Дисциплина = "БД" AND NOT EXISTS

    (SELECT ФИО FROM Rl WHERE ФИО=а.ФИО AND Дисциплина = "БД")

    Предикат EXISTS (SubQuery) истинен, когда подзапрос SubQuery не пуст, то есть содержит хотя бы один кортеж, в противном случае предикат EXISTS ложен.

    Предикат NOT EXISTS обратно - истинен только тогда, когда подзапрос SubQuery пуст.

    Обратите внимание, каким образом NOT EXISTS с вложенным запросом позволяет обойтись без операции разности отношений. Например, формулировка запроса со словом «все» может быть выполнена как бы с двойным отрицанием. Рассмотрим пример базы, которая моделирует поставку отдельных деталей отдельными поставщиками, она представлена одним отношением SP «Поставщики-детали» со схемой

    SP (Номер_поставщика. номер_детали) Р (номер_детали. наименование)

    Вот каким образом формулируется ответ на запрос: «Найти поставщиков, которые поставляют все детали».

    SELECT DISTINCT НОМЕР_ПОСТАВЩИКА FROM SP SP1 WHERE NOT EXISTS

    (SELECT номер_детали

    FROM P WHERE NOT EXISTS

    (SELECT * FROM SP SP2

    WHERE SР2.номер_поставщика=SР1.номер_поставщика AND

    sр2.номер_детали = Р.номер_детали)):

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

    SELECT DISTINCT Номер_поставщика

    GROUP BY Номер_поставщика

    HAVING CounKDISTINCT номер_детали) =

    (SELECT Count(номер_детали)

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

    Ключевое слово ANY, поставленное в любом предикате сравнения, означает, что предикат будет истинен, если хотя бы для одного значения из подзапроса предикат сравнения истинен. Ключевое слово ALL требует, чтобы предикат сравнения был бы истинен при сравнении со всеми строками подзапроса.

    Например, найдем студентов, которые сдали все экзамены на оценку не ниже чем «хорошо». Работаем с той же базой «Сессия», но добавим к ней еще одно отношение R4, которое характеризует сдачу лабораторных работ в течение семестра:

    R 1 = (ФИО, Дисциплина, Оценка);

    R 2 = (ФИО, Группа);

    R 3 = (Группы, Дисциплина)

    R 4 = (ФИО, Дисциплина, Номер_лаб_раб, Оценка);

    Select R1.ФИО From R1 Where 4 > = All (Select Rl.Оценка

    Where R1.Фио = R11.Фио)

    Рассмотрим еще один пример:

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

    Select R1.Фио

    From R1 Where R1.Оценка >= ANY (Select R4.Оценка

    Where Rl.Дисциплина = R4. Дисциплина AND R1.Фио = R4.Фио)