Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
базы данных.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
214 Кб
Скачать
☆

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

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

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

FROM R1 AS A, R1 AS B

или

FROM R1 A, R1 B;

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

Примеры вложенных запросов для базы данных «Перевозки»:

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

SELECT  Фамилия, Километраж

FROM Водители, Поездки

WHERE Личный_номер = Личный_номер_вод AND Километраж in

(SELECT MAX(Километраж) FROM Поездки)

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

SELECT DISTINCT Фамилия, Личный_номер

FROM Водители LEFT JOIN Поездки ON (Личный_номер=Личный_номер_вод)

WHERE Личный_номер not in

(SELECT Личный_номер_вод FROM Поездки

WHERE MONTH(Дата)= MONTH(GETDATE()) and YEAR(Дата)= YEAR(GETDATE()))

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

SELECT Водители.*, Транспорт.*

FROM Водители

JOIN Поездки on (Личный_номер=Личный_номер_вод)

JOIN Транспорт on (Поездки.Номер_авто = Транспорт.Номер)

WHERE Километраж >(SELECT AVG(Километраж)FROM Поездки)

 

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

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

Обратите внимание, каким образом NOT EXISTS с вложенным запросом позволяет обойтись без операции разности отношений. Например, формулировка запроса со словом "все" может быть выполнена как бы с двойным отрицанием.

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

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

В начало

15 Связанные запросы.

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

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

SELECT * FROM SalesPeople Main WHERE 1<(SELECT COUNT(*) FROM Customer WHERE SNum=Main.SNum) //возвращает всех продавцов, обслуживших более одного покупателя SELECT * FROM Orders O1 WHERE Amt>(SELECT AVG(Amt) FROM Orders O2 WHERE O2.CNum=O1.CNum) //возвращает все заказы, величина которых превосходит среднюю величины заказа для данного покупателя

В начало