Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Практические SQL запросы на выборку.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
9.64 Mб
Скачать

Как any может стать неоднозначным

Как подразумевалось выше, ANY не полностью однозначен. Если мы создаем запрос чтобы выбрать заказчиков которые имеют больший рейтинг чем любой заказчик в Риме, мы можем получить вывод который несколько отличался бы от того что мы ожидали (как показано в Рисунке 9 ):

SELECT *

FROM Customers

WHERE rating>ANY

( SELECT rating

FROM Customers

WHERE city='Rome' );

В Английском языке, способ которым мы обычно склонны интерпретировать оценку «больше чем любой (где city = Rome)» , должен вам сообщить что это значение оценки должно быть выше чем значение оценки в каждом случае где значение city = Rome. Однако это не так, в случае ANY - используемом в SQL. ANY оценивает как верно, если подзапрос находит любое значение которое делает условие верным.

Рисунок 9 Как оператор «больше чем» ( >) интерпретируется ANY

Чтобы дать другой пример, предположим что мы должны были выбирать все продажи сумм приобретений которые были больше чем по крайней мере один из порядков на 6-е Октября:

SELECT *

FROM Orders

WHERE amt > ANY

( SELECT amt

FROM Orders

WHERE odate = #10/06/1990# );

Вывод для этого запроса показывается в Рисунке 10.

Рисунок 10 Выбранное значение больше чем любое(ANY) на 6-е Октября

Даже если самая высокая сумма приобретений в таблице (9891.88) - имелась на 6-е Октября, предыдущая строка имеет более высокое значение суммы чем другая строка на 6-е Октября, которая имела значение суммы = 1309.95. Имея реляционный оператор ">=" вместо просто " > ", эта строка будет также выбрана, потому что она равна самой себе. Конечно, вы можете использовать ANY с другой SQL техникой, например с техникой объединения. Этот запрос будет находить все порядки со значением суммы меньшей чем значение любой суммы для заказчика в San Jose. (вывод показывается в Рисунке 11):

SELECT *

FROM Orders

WHERE amt<ANY

( SELECT amt

FROM Orders a, Customers b

WHERE a.cnum=b.cnum

AND b.city ='San_Jose' );

Даже если наименьший порядок в таблице был для заказчика из San Jose, то был второй наибольший; следовательно почти все строки будут выбраны. Простой способ запомнить, что < ANY значение меньшее чем наибольшее выбранное значение, а > ANY значение большее чем наименьшее выбранное значение.

Рисунок 11 Использование ANY с объединением

Фактически, вышеуказанные команды весьма похожи на следующее - (вывод показан на Рисунке 13):

SELECT *

FROM Orders

WHERE amt<(SELECT MAX (amt)

FROM Orders a, Customers b

WHERE a.cnum=b.cnum

AND b.city='San_Jose' );

Рисунок 12 Использование агрегатной функции вместо ANY

Специальный оператор all

С помощью ALL, предикат является верным, если каждое значение выбранное подзапросом удовлетворяет условию в предикате внешнего запроса. Если мы хотим пересмотреть наш предыдущий пример чтобы вывести только тех заказчиков чьи оценки, фактически, выше чем у каждого заказчика в Rome, мы можем ввести следующее чтобы произвести вывод показанный в Рисунке 13:

SELECT *

FROM Customers

WHERE rating>ALL

(SELECT rating

FROM Customers

WHERE city='Rome');

Рисунок 13 Использование оператора ALL

Этот оператор проверяет значения оценки всех заказчиков в Риме. Затем он находит заказчиков с оценкой большей чем у любого из заказчиков в Риме. Самая высокая оценка в Риме - у Giovanni (200). Следовательно, выбираются только значения выше этих 200.

Как и в случае с ANY, мы можем использовать EXISTS для производства альтернативной формулировки такого же запроса - (вывод показан на Рисунке 14):

SELECT *

FROM Customers outers

WHERE NOT EXISTS

( SELECT *

FROM Customers inners

WHERE outers.rating<=inners.rating

AND inners.city = 'Rome' );

Рисунок 14 Использование EXISTS в качестве альтернативы к ALL