<���оператор сравнения SOME|ANY () SOMEи ANYявляются синонимами, т.е. может использоваться любое из них. Результатом подзапроса является одинстолбец величин. Если для какого-нибудь значения V, получаемого из подзапроса, результат операции " V " равняется TRUE, то предикат ANYтакже равняется TRUE.
ALL ()
исполняется так же, как и ANY, но для всех значений, получаемых из подзапроса, проверка должна удовлетворять результату TRUE для предиката " V " .
Пример. Найти поставщиков компьютеров, моделей которых нет в продаже (т.е. отсутствуют в таблице PC):
SELECT DISTINCT maker
FROM Product
WHERE type = 'PC' AND NOT model = ANY
(SELECT model
FROM PC);
Оказалось, что только у поставщика Е есть модели отсутствующие в продаже:
Рассмотрим подробно этот пример. Предикат
model = ANY (SELECT model FROM PC);
вернет значение TRUE, если модель, определяемая полем model основного запроса, найдется в списке моделей таблицы PC (возвращаемом подзапросом). Поскольку предикат используется в запросе с отрицанием NOT, то значение TRUE будет получено, если модели не окажется в списке. Этот предикат проверяется для каждойзаписи основного запроса, которыми являются все модели ПК (предикат type = 'PC') из таблицы Product. Результирующий набор состоит из одногостолбца - имени производителя. Чтобы один производитель не выводился несколько раз (что может случиться, если он производит несколько моделей, отсутствующих в таблице PC), используется служебное слово DISTINCT.
Пример. Найти модели и цены ПК-блокнотов, стоимость которых превышает стоимость любого ПК:
SELECT DISTINCT model, price
FROM Laptop
WHERE price ALL
(SELECT price
FROM PC);
model
|
price
|
1298
|
1050.0
|
1750
|
1200.0
|
1752
|
1150.0
|
Приведем формальные правила оценки предикатов, использующих параметры ANY| SOMEи ALL:
* Если определен параметр ALLили SOMEи все результаты сравнения значения выражения и каждогозначения, полученного из подзапроса, являются TRUE, истинностное значение равно TRUE.
* Если результат выполнения подзапроса не содержит строк и определен параметр ALL, результат равен TRUE. Если же определен параметр SOME, результат равен FALSE.
* Если определен параметр ALLи результат сравнения значения выражения хотя бы с одним значением, полученным из подзапроса, является FALSE, истинностное значение равно FALSE.
* Если определен параметр SOMEи хотя бы один результат сравнения значения выражения и значения, полученного из подзапроса, является TRUE, истинностное значение равно TRUE.
* Если определен параметр SOMEи каждое сравнение значения выражения и значений, полученных из подзапроса, равно FALSE, истинностное значение тоже равно FALSE.
* В любом другомслучае результат будет равен UNKNOWN.
Заметим, что в общем случае запрос возвращает множествозначений. Поэтому использование подзапроса в предложении WHEREбез операторов EXISTS, IN, ALLи ANY, которые дают булевозначение, может привести к ошибке времени выполнения запроса.
Пример. Найти модели и цены ПК, стоимость которых превышает минимальную стоимость ПК-блокнотов:
SELECT DISTINCT model, price
FROM PC
WHERE price
(SELECT MIN(price)
FROM Laptop);
Этот запрос вполне корректен, т.к. скалярное значение price сравнивается с подзапросом, который возвращает единственное значение. В результате получим три модели ПК:
model
|
price
|
1121
|
850.0
|
1233
|
950.0
|
1233
|
980.0
|
Однако, если в ответ на вопрос "найти модели и цены ПК, стоимость которых совпадает со стоимостью ПК-блокнота" написать следующий запрос:
SELECT DISTINCT model, price
FROM PC
WHERE price =
(SELECT price
FROM Laptop);
то при выполнении последнего мы можем получить такое сообщение об ошибке:
Эта ошибка будет возникать при сравнении скалярного значения с подзапросом, который либо возвращает более одного значения, либо ни одного.
Читать дальше