2.11.    Использование оператора EXISTS

Используемый в SQL оператор EXISTS (существует) гене рирует значение истина или ложь, подобно булеву выражению Используя подзапросы в качестве аргумента, этот операто оценивает результат выполнения подзапроса как истинный если этот подзапрос генерирует выходные данные, то ест в случае существования (возврата) хотя бы одного найденного значения. В противном случае результат подзапроса ложный Оператор EXISTS не может принимать значение UNKNOWN (не известно).

Пусть, например, нужно извлечь из таблицы EXAM MARK данные о студентах, получивших хотя бы одну неудовлетвори тельную оценку.

SELECT DISTINCT STUDENT_ID FROM EXAM_MARKS A WHERE EXISTS (SELECT * FROM EXAM_MARKS В WHERE MARK < 3

AND  B.STUDENT_ID   =   A. STUDENT_ID) ;

При использовании связанных подзапросов предложение EXISTS анализирует каждую строку таблицы, на которую имеет­ся ссылка во внешнем запросе. Главный запрос получает стро­ки-кандидаты на проверку условия. Для каждой строки-канди­дата выполняется подзапрос. Как только подзапрос находит строку, где в столбце MARK значение удовлетворяет условию, он прекращает выполнение и возвращает значение истина внешне­му запросу, который затем анализирует свою строку-кандидата.

Например, требуется получить идентификаторы предме­тов обучения, экзамены по которым сдавались не одним, а не­сколькими студентами:

SELECT DISTINCT SUBJ_ID FROM EXAM_MAR KS A WHERE EXISTS (SELECT * FROM EXAM_MARKS В WHERE A.SUBJ_ID = B.SUBJ_ID

AND A.STUDENTJD < > B.STUDENTJD);

Часто EXISTS применяется с оператором NOT (по-русски NOT EXISTS интерпретируется, как «не существует»). Если предыдущий запрос сформулировать следующим образом найти идентификаторы предметов обучения, которые сдавались одним, и только одним студентом (другими словами, для кото­рых не существует другого сдававшего студента), то достаточно просто поставить NOT перед EXISTS.

Следует иметь в виду, что в подзапросе, указываемом в опе­раторе EXISTS, нельзя использовать агрегирующие функции.

Возможности применения вложенных запросов весьма раз­нообразны. Например, пусть из таблицы STUDENT требуется извлечь строки для каждого студента, сдавшего более одного I предмета.

SELECT *

FROM   STUDENT FIRST WHERE EXISTS

(SELECT SUBJ_ID FROM EXAM_MARKS SECOND GROUP BY SUBJ_ID HAVING COUNT (SUBJ_IDj   > 1

WHERE FIRST.STUDENT  ID =  SECOND. STUDENT ID);

Упражнения

1. Напишите запрос с EXISTS, позволяющий вывести данные обо всех студентах, обучающихся в вузах, которые имеют рейтинг вы­ше 300

2. Напишите предыдущий запрос, используя соединения.

3. Напишите запрос с EXISTS, выбирающий сведения обо всех сту­дентах, для которых в том же городе, где живет студент, существу­ют университеты, в которых он не учится.

4. Напишите запрос, выбирающий из таблицы SUBJECT данные о на­званиях предметов обучения, экзамены по которым сданы более чем одним студентом.