Материал: Graber_Martin_-_SQL_dlya_prostykh_smertnykh_-_2014

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Глава 13. Использование операторов ANY, ALL и SOME

Оператор ANY может использовать другие операторы отношения кроме равенства и, следовательно, выполняет сравнения, отличные от сравнений в IN. Например, мож­ но найти всех продавцов, имеющих покупателей, имена которых следуют в алфавит­ ном порядке за именем продавца (выходные данные представлены на рис. 13.3):

SELECT *

FROM Salespeople WHERE sname < ANY

(SELECT cname

FROM Custome rs);

Все строки, которые были выбраны, сохраняются для Serres и Rifkin, поскольку они не имеют покупателей, имена которых следуют за их именами в алфавитном по­

рядке. Это эквивалентно следующему запросу с EXISTS, выходные данные для кото­

рого представлены на рис. 13.4:

SELECT *

FROM Salespeople outer WHERE EXISTS

(SELECT *

FROM Customers inner

WHERE outer.sname < inner.cname);

Любой запрос, сформулированный с ANY (или с ALL), можно сформулировать и с

EXISTS, хотя обратное утверждение неверно. Строго говоря, версии с EXISTS не со­

всем идентичны версиям с ANY или ALL. Различие заключается в обработке NULL- значений (эта проблема будет рассмотрена позже в этой главе). Можно обойтись без

____

_

_ _.__ ~о~

Excct1t 1ог1 Lоч--- ~~- -

--- 1

 

Sl L f (

1

•

 

< ANY

 

1

 

1lw11LHt

 

·~r11111L>

 

1

• ROM

S,1 I

,рсор 1t-'

 

1

''( Ч l l

(

1

r 11,;me

 

1

11 f<Ol·l

С 1Jst omc·rs)

 

 

 

 

 

,,,,",

London

" .•r"м

 

 

 

*""'1'*1

 

 

 

 

 

001

Peel

. 12

 

 

 

 

 

1004

Mot1ka

London

0. 11

 

 

 

 

 

100}

Axelrod

New Vork

l1J. 10

 

 

Рис. 13.3. Использование ANY с неравенством

130

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

-

-

 

-----==----=

-

-

~01

fxeCl•t

ior1 1 ос1

------=--

- 1

 

~1 l L l

I

 

•

 

 

 

 

 

 

 

 

1

 

1 ll~OM

~d.1(»µ1--'upJ~·

011{Pt

 

 

 

 

 

 

,Wllf !!!

 

f

Х J С:, 1::,

 

 

 

 

 

 

1

('! 11

(

1

•

 

 

 

 

 

 

 

 

 

 

 

] t l~1Jf\l

(

ll

t

оп

r

J r

11r

'

 

 

 

1

 

W11! fJI

 

u11t

f r

11

1'1<

<

1 г

rlf''c.:r1 illlf-)

 

 

 

 

 

 

 

11111111

Peel

 

 

london

 

i'"'*. 12

 

 

 

 

 

 

 

 

 

*"''*

 

 

london

 

111. 11

 

 

 

 

 

1llH/14

Motika

 

 

 

 

 

 

 

 

1111111}

Axelrod

 

New York

 

". 1 fll

.~

 

 

 

 

 

 

 

 

 

•

• 1

 

 

 

 

,'

 

 

 

 

 

 

 

 

 

 

 

 

1

 

l

 

 

 

 

 

 

 

 

--~

 

--__

1

 

Рис. 13.4. Использование EXISTS как альтернативы ANY

ANY и ALL, если умело применять EXISTS (и IS NULL). Многие пользователи счита­ ют, что использовать ANY и ALL проще, чем EXISTS, который требует связанных под­ запросов. В зависимости от практической реализации, ANY и ALL могут, по крайней мере теоретически, быть более эффективными по сравнению с EXISTS. Подзапрос с ANY или ALL можно выполнять один раз для каждой строки основного запроса и пре­ доставлять выходные данные для определения предиката. С другой стороны, EXISTS использует связанный подзапрос, который требует повторного выполнения всего подза­ проса для каждой строки основного запроса. SQL пытается найти наиболее эффектив­ ный способ выполнения любой команды, поэтому он может пытаться преобразовать менее действенную формулировку запроса в более эффективную (но нельзя рассчиты­ вать на то, что при этом будет найдена наиболее эффективная формулировка).

Основная причина предложения формулировки с EXISTS, как альтернативы ANY и ALL, состоит в противоречии ANY и ALL интуиции, связанной со спецификой приме­

нения этих терминов в английском языке. Если вы научитесь применять разные спосо­

бы формулировки данного запроса, у вас появится возможность разработать множество

процедур для сложных или неясных случаев.

Неоднозначности при использовании ANY

ANY не является полностью интуитивно очевидным. Если запрос формулируется для выбора покупателей, имеющих рейтинг, превышающий рейтинг любого покупате­

ля в Rome, можно получить выходные данные, которые отличаются от ожидаемых (как показано на рис. 13.5):

SELECT •

131

Глава 13. Использование 01tераторов ANY, ALL и SOME

Рис. 13.5. Больше, чем ANY в интерпретации SQL

FROM Customers

WHERE rating > ANY

(SELECT rating

FROM Customers

WHERE city = 'Rome');

В английском языке выражение "рейтинг больше, чем любой (апу) другой (где поле city равно Rome)", обычно интерпретируется так: значение данного рейтинга должно быть выше, чем значение рейтинга для каждого (eve1y) случая, когда значение поля city равно Rome. Однако в SQL оператор ANY интерпретируется иначе. ANY оценива­ ется как истина, если подзапрос находит любое (апу) значение (любые значения), удов­ летворяющее (удовлетворяющие) условию.

Если бы ANY интерпретировалось как обычное слово английского языка, покупате­ ли с рейтингом 300 оказались бы выше Giovanni, находящегося в Rome и имеющего рейтинг 200. Однако, подзапрос с ANY находит также и Periera из Rome с рейтингом 100. Все покупатели с рейтингом 200 были выбраны (поскольку их рейтинги превыша­ ют 100) несмотря на то, что в Rome был другой покупатель (Giovanni), рейтинг которого выше 200 (то, что один из выбранных покупателей тоже находится в Rome, здесь значе­ ния не имеет). Они были выбраны, поскольку подзапрос сгенерировал значение, сделав­

шее предикат истинным для этих строк.

Другой пример: предположим, нужно выбрать все заказы, величина которых пре­ восходит величину по крайней мере одного из заказов, сделанных 6 октября 1990 года:

SELECT *

FROM Orders

132

San Jose

СпециШlьный оператор ANY или SOME

WHERE amt > ANY (SELECT amt

FROM Orders

WHERE odate = 10/06/1990);

Выходные данные для запроса представлены на рис. 13.6.

Даже если наибольшая величина заказов, представленных в таблице (9891.88), приходится на 6 октября, предшествующие строки имеют значения, превышающие значение поля amounts в другой строке таблицы за 6 октября 1990 года - 1309.95.

Рис. 13.6. Выбор записей, значение поля amt которых превышает ANY на 6 октября

Если бы использовался оператор отношения>= вместо просто>, эта строка тоже была бы выбрана, так как она равна сама себе.

Можно использовать ANY с другими SQL-средствами, например, с соединениями. Этот запрос отыскивает все заказы, величина которых меньше величины заказа любого покупателя в (выходные данные представлены на рис. 13.7):

SELECT *

FROM Orders

WHERE amt < ANY

(SELECT amt

FROM Orders a,Customers Ь

WHERE a.cnum = b.cnum

AND b.city = 'San Jose');

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

133

Глава 13. Использование операторов ANY, ALL и SOME

**ililШM

311101

31111113 767.19 10/03/199111

31111112 19111111.1111 1111/1113/199111

311106 1098.16 10/1113/1990

31111119 1713.23 1111/04/199111

31111117 75.75 10/1114/199111

3008 4723.1110 10/05/1990

31111111 131119.95 10/06/199111

- - -l:Jr Ov/SC

ri~~ р Dn р u --·1

Рис. 13. 7. Использование ANY с JOIN (соединением)

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

нить, что< ANY означает "меньше, чем наибольшее выбранное значение", а> ANY означает "больше, чем наименьшее выбранное значение". Фактически, такую коман­ ду можно сформулировать следующим образом (выходные данные представлены на

рис. 13.8):

134

Источник: https://studfile.net/preview/16418473/