Запрос, выводящий ФИО и оклад работников, оклад которых выше средне-
го, может иметь следующий вид:
SELECT ФИО, Оклад
FROM Зарплата
WHERE Оклад >
(SELECT AVG(Оклад) FROM Зарплата)
ORDER BY ФИО;
Для того чтобы выполнить проверку условия «выше среднего», требуется
вычислить это самое среднее. Эту работу выполняет вложенный запрос, кото-
рый обращается к той же самой таблице «Зарплата».
Вложенный запрос, для которого используются подобные операции сравне-
ния, должен гарантированно выдавать только одну результирующую запись,
состоящую только из одного столбца.
Пример 1.13. Запрос выводит список работников, получающих максималь-
ный оклад:
SELECT ФИО, Оклад
FROM Зарплата
WHERE Оклад =
(SELECT MAX(Оклад) FROM Зарплата)
ORDER BY ФИО;
Вместе с операциями сравнения могут быть использованы операторы ALL
(все) и ANY (какой-нибудь). ALL требует, чтобы заданное условие выполня-
лось для всех записей из вложенного запроса, ANY - хотя бы для одной.
Пример 1.14. Запрос выполняет те же действия, что и предыдущий:
SELECT ФИО, Оклад
FROM Зарплата
WHERE Оклад >= ALL
(SELECT Оклад FROM Зарплата)
ORDER BY ФИО;
При использовании операторов ALL и ANY, вложенный запрос может вы-
давать любое количество строк (записей), но в нем также должен быть только
один столбец (запросы такого вида называют скалярными).
Пример 1.15. Вывести список работников, оклад которых НЕ САМЫЙ
НИЗКИЙ (есть кто-то, кто получает еще меньше):
SELECT ФИО, Оклад
FROM Зарплата
WHERE Оклад > ANY
(SELECT Оклад FROM Зарплата)
ORDER BY ФИО;
Пример 1.16. Эту же задачу можно решить иначе, без оператора ANY:
SELECT ФИО, Оклад
FROM Зарплата
WHERE Оклад <>
(SELECT MIN(Оклад) FROM Зарплата)
ORDER BY ФИО;
Для работы с вложенными запросами также существуют операторы IN и
NOT IN. Оператор IN требует, чтобы значение его левого аргумента содержа-
лось в результирующем наборе правого аргумента (вложенного запроса). Опе-
ратор NOT IN имеет противоположное назначение.
Пример 1.17. Список работников с окладом выше среднего:
SELECT ФИО, Оклад
FROM Зарплата
WHERE Оклад NOT IN (
SELECT Оклад FROM Зарплата
WHERE Оклад <=
(SELECT AVG(Оклад) FROM Зарплата)
)
ORDER BY ФИО;
Данный запрос составлен исключительно с целью проиллюстрировать ра-
боту оператора IN, ранее (пример 1.12) был приведен более простой запрос,
выполняющий те же действия.
Нетрудно убедиться, что IN можно заменить на «= ANY», а NOT IN на «<>
ALL».
Как видно из приведенного примера, вложенные запросы в предложении
WHERE также могут иметь больше одного уровня вложенности.
Для обработки вложенных запросов могут использоваться операторы
EXISTS (существует) и NOT EXISTS (не существует). Оператор EXISTS воз-
вращает значение «истина», если вложенный запрос содержит хотя бы одну за-
пись (не важно, с какими данными). Оператор NOT EXISTS имеет противопо-
ложное назначение.
Пример 1.18. Список работников, у которых НЕ самый низкий оклад (это
уже третий вариант запроса для решения той же самой задачи – см. примеры
1.15, 1.16):
SELECT ФИО, Оклад
FROM Зарплата AS Зп1