Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Сложные запросы ч6.doc
Скачиваний:
4
Добавлен:
09.09.2019
Размер:
70.66 Кб
Скачать

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

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

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

В SQL сложные запросы получаются из других запросов следующими способами:

  1. вложением SQL-выражения запроса в SQL -выражение другого запроса. Первый из них называют подзапросом, а второй— внешним или основным запросом;

  2. применением к SQL-запросам операторов объединения и соединения наборов записей, возвращаемых запросами. Эти операторы называют теоретико-множественными или реляционными.

Подзапросы

Подзапрос — это SQL -выражение, начинающееся с оператора

SELECT, которое содержится в условии оператора WHERE ИЛИ HAVING для другого запроса. Таким образом, подзапрос — это запрос на выборку данных, вложенный в другой запрос. Внешний запрос, содержащий подзапрос, если только он сам не является подзапросом, не обязательно должен начинаться с оператора SELECT. В свою очередь, подзапрос может содержать другой подзапрос и т. д. При этом сначала выполняется подзапрос, имеющий самый глубокий уровень вложения, затем содержащий его подзапрос и т. д. Часто, но не всегда, внешний запрос обращается к одной таблице, а подзапрос — к другой. На практике именно этот случай наиболее интересен.

Простые подзапросы

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

Рассматривая простые подзапросы, следует выделить три частных случая:

  • подзапросы, возвращающие единственное значение;

  • подзапросы, возвращающие список значений из одного столбца таблицы;

  • подзапросы, возвращающие набор записей.

Рассмотрим эти частные случаи более подробно.

Работа с единственным значением

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

SELECT *

FROM Клиенты

WHERE Сумма заказа > (SELECT AVG(сумма_заказа) FROM Клиенты);

В данном запросе сначала выполняется подзапрос

(SELECT AVG(сумма_заказа) FROM клиенты).

Он возвращает единственное значение (а не набор записей) — среднее значение столбца сумма_заказа.

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

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

Попытка выполнить следующий простой запрос приведет к ошибке:

SELECT * FROM клиенты

WHERE Сумма заказа > AVG(сумма_заказа);

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

Подзапрос, вообще говоря, может возвращать несколько записей.: Чтобы в этом случае в условии внешнего оператора WHERE можно было использовать операторы сравнения, требующие единственного значения, используются кванторы, такие как ALL (все) и SOME(некоторый).

Допустим, в базе данных имеются две таблицы:

  • Сотрудники (имя, зарплата), содержащая значения зарплаты для сотрудников некоторой фирмы;

  • Ср_зарплата_в_промышленности (Тип промышленности, Ср_зарплата), содержащая значения среднего уровня зарплаты для различных типов промышленности.

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

SELECT Сотрудники.Имя FROM Сотрудники

WHERE Сотрудники. Зарплата >

ALL (SELECT Cp_зарплата FROM Cp_зарплата_в_промышленности);

В данном примере используются полные имена столбцов, содержащие в качестве префиксов имена таблиц. Подзапрос (SELECT Ср_зарплата FROM Ср_зарплата_в_промышленности) возвращает список средних зарплат для различных типов промышленности. Выражение > ALL (больше всех) означает, что внешний запрос должен вернуть только те значения столбца Зарплата из таблицы сотрудники, которые больше каждого значения, возвращенного вложенным подзапросом.

Результатный список сотрудников будет иным, если вместо квантора ALL применить SOME или ANY:

SELECT Сотрудники.Имя FROM Сотрудники

WHERE Сотрудники. Зарплата >

SOME (SELECT Cp_зарплата FROM Ср_зарплата_в_промышленности);

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

Разумеется, вложенные подзапросы могут содержать условия, определяемые оператором WHERE.

Теперь рассмотрим запросы с кванторами ALL и SOME для более общего случая. Пусть имеются две таблицы: т1, содержащая как минимум столбец А, и т2, содержащая, по крайней мере, один столбец B. Тогда запрос с квантором ALL можно сформулировать следующим образом:

SELECT А FROM Tl

WHERE А оператор сравнения

ALL (SELECT В FROM T2);

Здесь оператор сравнения обозначает любой оператор сравнения.

Данный запрос должен вернуть список всех тех значений столбца А, для которых. оператор сравнения истинен для всех значений столбца B.

Запрос с квантором SOME, очевидно, имеет аналогичную структуру. Он должен вернуть список всех тех значений столбца A, для которых оператор сравнения истинен хотя бы для какого-нибудь одного значения столбца B.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]