|
|||||
Реализация вложенных запросовДата добавления: 2014-11-24 | Просмотров: 1537
В состав условий в предложении WHERE (или HAVING) могут входить команды SELECT, образуяподзапросы. Согласно стандарту SQL предикаты, использующие подзапросы, имеют исключительно следующий вид: < скалярное выражение > < оператор > < подзапрос > То есть нельзя использовать предикаты с подзапросами такого вида: < подзапрос > < оператор > < скалярное выражение > или < подзапрос > < оператор > < подзапрос >. Например, нельзя писать так: SELECT * FROM Заказы WHERE ( SELECT DISTINCT Номер_заказчика FROM Заказы WHERE Номер_продавца= 2001 ) = Номер_заказчика; В строгой реализации стандарта SQL это приведет к ошибке, хотя некоторые программы и допускают такую форму предиката. В стандарте SQL/89 к подзапросам применяется еще одно ограничение, состоящее в том, что результирующая таблица должна содержать только один столбец. Поэтому в предложении SELECT подзапроса в качестве списка выборки может быть указано единственное арифметическое выражение. Конструкция внешнего запроса зависит от количества значений, возвращаемых подзапросом. Возможны два случая: внутренний запрос возвращает одно значение или несколько значений (более одной строки для одного столбца). Пример использования вложенного запроса, который возвращает одно значение: даны таблица Товар с полями Название_товара, Да-та_продажи, Номер_покупателя и таблица Покупатель с полями Но-мер_покупателя и Имя_покупателя. Для вывода названий товаров и даты их продажи фирме “АВС” можно выполнить запрос: SELECT Название_товара, Дата FROM Товар WHERE Номер_покупателя = (SELECT Номер_покупателя FROM Покупатель WHERE Имя_покупателя= “АВС”) ORDER BY Название товара; Если подзапрос возвращает не одну, а несколько строк, то в предложение WHERE необходимо включать предикаты, позволяющие воспринять несколько значений, например, предикаты IN, ANY и ALL. Примеры. 1) Вывести названия товаров и их количество на тех складах, на которых товаров меньше, чем на любом из складов Одессы SELECT Название_товара, Количество, Город FROM Товар WHERE Количество< ANY (SELECT Количество FROM Склад WHERE Город= “Одесса”) ORDER BY Название_товара; 2) Вывести названия товаров и их количество на тех складах, на которых товаров больше, чем на других складах Киева SELECT Название_товара, Количество, Город FROM Товар WHERE Количество > ALL (SELECT Количество FROM Склад WHERE Город= “Киев”) ORDER BY Название_товара; Для возврата единственного значения из внутреннего запроса часто также используются функции агрегирования. Пример. Вывести список сотрудников, оклад которых выше среднего. SELECT Фамилия, Оклад FROM Сотрудник WHERE Оклад > (SELECT АVG(Оклад) FROM Сотрудник) ORDER BY Фамилия; Можно создавать запросы с неограниченным кол-вом уровней вложенности. Так как подзапрос всегда вложен в некоторый другой оператор SQL, то вместо констант в арифметическом выражении выборки и логических выражениях разделов WHERE и HAVING этого подзапроса можно использовать значения столбцов текущих строк таблиц, участвующих в (под)запросах более внешнего уровня. Таким образом, существуют два основных типа вложенных запросов:простые и коррелированные (или соотнесенные). В простых вложенных запросах подзапрос выполняется независимо от внешнего запроса, и его результаты используются для выполнения внешнего запроса. В коррелированном запросе внутренний запрос обращается одновременно к своей таблице данных и таблице данных внешнего запроса. При этом подзапрос выполняется неоднократно, по одному разу для каждой строки таблицы основного запроса. Пример. Найти всех заказчиков, сделавших заказы 3-его Октября SELECT * FROM Заказчики Внешняя WHERE 10/03/1999 IN ( SELECT Дата_заказа FROM Заказчики Внутренняя WHERE Внешняя .Номер_заказчика = Внутренняя.Номер_заказчика ); Так как значение в поле Номер_заказчика внешнего запроса меняется, внутренний запрос должен выполняться отдельно для каждой строки внешнего запроса. Если соотнесенный подзапрос находится внутри предложения HAVING, то в качестве внешних ссылок можно использовать только поля, использованные в предложении GROUP BY. Подзапрос будет выполняться один раз для каждой группы, сформированной из внешнего запроса, а не для каждой строки. |
При использовании материала ссылка на сайт Конспекта.Нет обязательна! (0.027 сек.) |