Запросы, которыми управляют другие запросы, называются вложенными. Прежде чем выполнить основной запрос, SQL сначала оценит внутренний запрос ( подзапрос ) внутри предложения WHERE. Подзапрос должен выбрать только одно поле, а тип данных этого поля должен совпадать с тем значением, с которым он будет сравниваться в предикате. Предикаты с подзапросами являются необратимыми, т.е. предикаты, включающие подзапросы, используют конструкции в следующем порядке:
< выражения > < оператор >< подзапрос >,
· В подзапросах допускается использование агрегатных функций.
· В подзапросах предложения GROUP BY или HAVING будут отклонены.
· Оператор BETWEEN, LIKE и IS NULL не могут использоваться подзапросами.
· Оператор IN позволяет использовать подзапросы, которые производят любое число строк. IN определяет набор значений предиката, одно из которых должно совпадать с другими по порядку. При использовании IN с подзапросом, SQL просто формирует этот набор из вывода подзапроса, а значит, допускается использование IN для того, чтобы выполнить такой же подзапрос.
· Подзапросы всегда определяют одиночные столбцы - это обязательно, поскольку выбранный вывод сравнивается с одиночным значением.
· Команда SELECT не может использоваться в подзапросе.
· Можно использовать подзапросы внутри предложения HAVING.
· Если подзапрос не выводит никаких значений, то основной запрос также не выводит никаких значений.
Пример 1. Найти информацию об успеваемости студента Полякова, для которого известен его номер. В этом случае необходимо извлечь этот номер из таблицы с данными о студентах, и после этого применять результат к таблице успеваемости.
Пример 7. Подсчитать количество студентов с оценками выше средней, чем по дисциплине с PNUM = 2003
SELECT OCENKA, COUNT( DISTINCT SNUM )
FROM USP
GROUP BYOCENKA
HAVINGOCENKA>=
(SELECT AVG (OCENKA)
FROM USP
WHERE PNUM = 2003);
Результат запроса:
OCENKA
---------------
5 2
4 2
6.2. Объединение запросов исключением подзапросов.
Внешнее объединение – это процесс объединения двух запросов, в котором второй запрос выбирает строки, исключенные первым.
Пример 1. Рассмотрим таблицу успеваемости студентов. Добавим в нее запись {1006, NULL, NULL, 3416 , NULL}.Необходимо просмотреть по дисциплине, не учитывая тех, кто еще не получил оценку.
7.3. Соотнесенные подзапросыпозволяют обратиться к внутреннему запросу таблицы в предложении внешнего запроса FROM, с помощью соотнесенного подзапроса. При этом подзапрос выполняется неоднократно, по одному раза для каждой записи таблицы основного запроса.
Строку внешнего запроса , для которой внутренний запрос каждый раз будет выполнятся , будем называть текущей строкой. С учетом этого, процедура оценки, выполняемой соотнесенным подзапросом:
· выбор строки из таблицы во внешнем запросе – это текущая строка;
· сохранение значение текущей строки в псевдониме, имя которого определено в предложении FROM внешнего запроса;
· выполнение подзапроса, при этом везде, где найден псевдоним из внешнего запроса, используется значение из текущей строки( это принято называть внешней ссылкой );
· оценка предиката внешнего запроса на основе результатов подзапроса;
· описанная выше последовательность повторяется для следующей строки из таблицы внешнего запроса, и так до тех пор, пока все строки не будут проверены.
Пример 1. Найти данные всех студентов, которые получали оценки 10/06/1999.
Пример 2. Вывести фамилии и номера всех студентов, которые получили более одной оценки.
SELECT SNUM, SFAM
FROM STUDENT FIRST
WHERE1<
(SELECT COUNT(*)
FROM USP
WHERE SNUM = FIRST. SNUM);
Результат запроса:
SNUM SFAM
-----------------------
3412 Поляков
Часто соотнесённый подзапрос используют на основе той же самой таблицы, что и основной запрос. Это даёт возможность извлечь сложные формы информации.
Пример 3. Найти все оценки по дисциплине со значениями, выше средней по той же дисциплине.
SELECT*
FROM USP FIRST
WHERE OCENKA >
(SELECT AVG ( OCENKA )
FROM USP SECOND
WHERE SECOND. PHUM = FIRST. PHUM);
Результат запроса: отсутствует.
Предложение HAVING может работать с соотнесёнными подзапросами, в этом случае предикат оценивается для каждой группы из внешнего запроса, а не для каждой строки.
Пример 4. Установить среднее значение оценок за каждый день, причем так, что это среднее должно быть больше или равно хотя бы наполовину баллов, чем минимальное значение оценки в этот день.