double arrow

Часть III. Операторы: EXISTS, ANY, SOME, ALL


Продолжаем обсуждение подзапросов. Сегодня рассмотрим специальные операторы, которые используют подзапросы в качестве аргументов. До сих пор, мы говорили с Вами о том, что на выходе подзапрос должен возвращать одно единственное значение. Допускалось использование подзапросов, которые на выходе давали ряд значений, но тогда мы оговаривали условие использования оператора IN. Сегодня Вы познакомитесь с новыми операторами, которые позволяют решить вопросы связанные с получением на выходе от подзапроса нескольких строк.

Оператора EXISTS. Данный оператор, используя подзапрос в качестве аргумента, оценивает его как истинный, если подзапрос генерирует выходные данные или как ложный, если на выходе подзапрос не содержит данных. Таким образом, в результате применения EXISTS к подзапросу получаем TRUE или FALSE.

Одной из особенностей использования EXISTS, является то, что он не может принимать значение UNKNOWN. Вполне логично: если на выходе подзапрос, который является аргументом EXISTS, генерирует данные, то возвращается правда, в противном случае - ложь. Исходя из предыдущих размышлений, замечу, что оператор EXISTS позволяет нам работать с несколькими строками группы значений, в отличие от остальных операторов используемых с подзапросами. Вы, наверное, заметили что, часто в SQL одну и ту же задачу возможно решить несколькими способами. Рассмотрим следующий пример: "Выбрать всех студентов, которые когда-либо пользовались услугами библиотеки."




SELECT *

FROM Students s

WHERE EXISTS (

SELECT *

FROM S_Cards c

WHERE s.id=c.id_student

)

ORDER BY 2;

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

Следующие два оператора абсолютно идентичны и являются взаимозаменяемыми: это ANY и SOME. Как работают данные операторы? Продемонстрируем это на примере известного Вам запроса: "Выбрать всех студентов, которые когда-либо пользовались услугами библиотеки."

SELECT *

FROM Students

WHERE id= ANY (

SELECT id_student

FROM S_Cards

)

ORDER BY 2;

Оператор ANY берет все значения поля id_student в таблице S_Cards и оценивает результат как истину, если какое-либо значение совпадает со значением поля id из текущей строки внешнего запроса. Конечно, аналогичного результата возможно добиться и при использование оператора SOME.

SELECT *

FROM Students

WHERE id= SOME (

SELECT id_student

FROM S_Cards

)

ORDER BY 2;

Еще один специальный оператор, который мы сегодня рассмотрим, это оператор ALL. Данный оператор возвращает значение TRUE, если каждое значение, выбранное в процессе выполнения подзапроса, удовлетворяет условию, заданному в условии внешнего запроса. Рассмотрим следующий пример: "Выбрать всех авторов, написавших книги с объемом страниц большим, чем любая книга выпущенная издательством Питер".



SELECT Authors.FirstName & ' ' & Authors.LastNAme AS [Полное имя]

FROM Authors, Books

WHERE Authors.Id=Books.Id_Author

AND Books.Pages>ALL(

SELECT Books.Pages

FROM Books, Press

WHERE (Books.Id_press=Press.ID) AND (Press.NAME='Питер')

);

Если бы мы записали данный запрос без оператора ALL, тогда бы мы получили сообщение об ошибке: "Данный подчиненный запрос должен возвращать не более одной записи". Используя же оператор ALL мы добиваемся следующего желаемого эффекта: вначале выполняется подзапрос, который на выходе дает несколько результирующих строк. Затем значение каждой результирующей строки сравнивается с значением поля Pages таблицы Books. Если, в каждом из случаев, значение поля Pages таблицы BOOK будет больше соответсвующего значения каждой из результирующих строк, то результатом работы Books.Pages>ALL (...) будет TRUE. Дальнейшая обработка происходит по уже известным Вам правилам.







Сейчас читают про: