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

Равенства и неравенства

ALL используется в основном с неравенствами чем с равенствами, так как значение может быть "равным для всех" результатом подзапроса только если все результаты, фактически, идентичны. Посмотрите следующий запрос:

SELECT *

FROM Customers

WHERE rating = ALL

(SELECT rating

FROM Customers

WHERE city='San_Jose' );

Эта команда допустима, но, c этими данными, мы не получим никакого вывода. Только в единственном случае вывод будет выдан этим запросом - если все значения оценки в San Jose окажутся идентичными. В этом случае, можно сказать следующее :

SELECT *

FROM Customers

WHERE rating =

( SELECT DISTINCT rating

FROM Customers

WHERE city='San Jose' );

Основное различие в том, что эта последняя команда должна потерпеть неудачу если подзапрос выведет много значений, в то время как вариант с ALL просто не даст никакого вывода. В общем, не самая удачная идея использовать запросы которые работают только в определенных ситуациях подобно этой. Так как ваша база данных будет постоянно меняться, это неудачный способ, чтобы узнать о ее содержании. Однако, ALL может более эффективно использоваться с неравенствами, то есть с оператором "< >". Но учтите что сказанное в SQL что - значение которое не равняется всем результатам подзапроса, - будет отличаться от того же но сказанного с учетом грамматики Английского языка. Очевидно, если подзапрос возвращает много различных значений, как это обычно бывает, ни одно отдельное значение не может быть равно им всем в обычном смысле. В SQL, выражение - < > ALL - в действительности соответствует " не равен любому " результату подзапроса. Другими словами, предикат верен, если данное значение не найдено среди результатов подзапроса. Следовательно, наш предыдущий пример противоположен по смыслу этому примеру (с выводом показанным в Рисунке 16):

SELECT *

FROM Customers

WHERE rating<>ALL

( SELECT rating

FROM Customers

WHERE city='San Jose' );

cnum cname city rating snum
Hoffman London
Clemens London
Pereira Rome

Рисунок 16 Использование ALL с < >

Вышеупомянутый подзапрос выбирает все оценки для города San Jose. Он выводит набор из двух значений: 200 (для Liu) и 300 (для Cisneros). Затем, основной запрос, выбирает все строки, с оценкой не совпадающей ни с одной из них - другими словами все строки с оценкой 100. Вы можете сформулировать тот же самый запрос используя оператор NOT IN:

SELECT*

FROM Customers

WHERE rating NOT IN

( SELECT rating

FROM Customers

WHERE city='San Jose' );

Вы могли бы также использовать оператор ANY:

SELECT *

FROM Customers

WHERE NOT rating = ANY

( SELECT rating

FROM Customers

WHERE city ='San Jose' );

Вывод будет одинаков для всех трех условий.