Структурированный язык запросов – SQL, страница 42
Чтобы выполнить основной запрос, SQL сначала должен оценить
внутренний запрос (его называют подзапросом) внутри предложения
WHERE. Происходит это традиционным образом, т.е. исполняется
вложенный запрос, извлекающий необходимые для определения значения
предиката данные, а только затем - основной. Разумеется, подзапрос должен
выбрать только одно поле, а тип данных этого поля должен совпадать с тем
значением, с которым он будет сравниваться в предикате.
С другой стороны, возможна ситуация, когда подзапрос выдает в качестве
результата несколько различных значений, что может сделать
невыполнимым оценку предиката основного запроса, и команда выдаст
ошибку. При использовании подзапросов в предикатах, основанных на
реляционных операторах, обязательно нужно убедиться, что использован
подзапрос, который будет отображать только одну строку вывода. Кроме
того, при использовании подзапроса, который вообще не выводит никаких
значений, основной запрос не выведет никаких значений: его предикат будет
иметь неизвестное значение.
В некоторых случаях стоит использовать DISTINCT для того, чтобы в
подзапросе получить одиночное значение. Предположим, что преподаватели
могут вести занятия по разным дисциплинам. Тогда для получения ответа на
вопрос о том, какие дисциплины ведет преподаватель Викулина, можно
воспользоваться запросом:
SELECT *
FROM PREDMET WHERE TNUM =
(SELECT DISTINCT TNUM FROM TEACHERS WHERE TFAM =
'Викулина');
В результате будет получено:
PNUM PNAME TNUM HOURS COURS
2001 Физика 4001 34 1
Подзапрос установил, что значение поля TNUM совпало с фамилией
Викулина при значении 4001, а затем основной запрос выделил все записи с
этим значением TNUM из таблицы предметов. Т.к., вообще говоря, могло
получиться, что преподаватель ведет несколько предметов, то фраза
DISTINCT в данном случае обязательна - если подзапрос возвратил бы более
одного значения, то это вызвало бы ошибку.
Следует иметь в виду, что предикаты с подзапросами являются
необратимыми, т.е. предикаты, включающие подзапросы, используют
конструкцию в следующем порядке:
<ВЫРАЖЕНИЕ> <ОПЕРАТОР> <ПОДЗАПРОС>,
и ни в коем случае не