Скачиваний:
25
Добавлен:
01.04.2014
Размер:
761.34 Кб
Скачать

162 Понимание sql

______________________________________________________________________

ГЛ. 13

SELECT *

FROM Customers

WHERE NOT rating = ANY

( SELECT rating

FROM Customers

WHERE city = " San Jose' );

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

ПРАВИЛЬНОЕ ПОНИМАНИЕ ANY И ALL

В SQL, сказать что - значение больше( или меньше ) чем любое(ANY) из на-

бора значений - тоже самое что сказать, что оно больше( или меньше ) чем

любое одно отдельное из этих значений. И наоборот, сказать что значение

не равно всему(ALL) набору значений, тоже что сказать, что нет такого зна-

чения в наборе которому оно равно.

КАК ANY, ALL, И EXIST ПОСТУПАЮТ

======= С ОТСУТСТВУЮЩИМИ И =======

НЕИЗВЕСТНЫМИ ДАННЫМИ

Как было сказано, имеются некоторые различия между EXISTS и операто-

рами представленными в этой главе относительно того как они обрабатыва-

ют оператор NULL. ANY и ALL также отличаются друг от друга тем как

они реагируют если подзапрос не произвел никаких значений чтобы исполь-

зовать их в сравнении. Эти различия могут привести к непредвиденным ре-

зультатам на Ваши запросы если вы не будете их учитывать.

КОГДА ПОДЗАПРОС ВОЗВРАЩАЕТСЯ ПУСТЫМ

Одно значительное различие между ALL и ANY - способ действия в cитуации

когда подзапрос не возвращает никаких значений. В принципе, всякий раз, ко-

гда допустимый подзапрос не в состоянии сделать вывод, ALL - автоматически

верен, а ANY автоматически неправилен. Это означает, что следующий запрос

SELECT *

FROM Customers

WHERE rating > ANY

( SELECT rating

FROM Customers

WHERE city = Boston );

ИСПОЛЬЗОВАНИЕ ОПЕРАТОРОВ ANY, ALL, И SOME 163

______________________________________________________________________

не произведет никакого вывода, в то время как запрос -

SELECT

FROM Customers

WHERE rating > ALL

( SELECT rating

FROM Customers

WHERE city = 'Boston' );

выведет всю таблицу Заказчиков. Когда нет никаких заказчиков в Boston,

естественно, ни одно из этих сравнений не имеет значення.

ANY И ALL ВМЕСТО EXISTS С

ПУСТЫМ УКАЗАТЕЛЕМ( NULL )

Значения NULL также имеют некоторые проблемы с операторами наподо-

бии этих. Когда SQL сравнивает два значения в предикате, одно из кото-

рых пустое (NULL), то результат неизвестен ( смотрите Главу 5 ).

Неизвестный предикат, подобен неверному и является причиной того что

строка не выбирается, но работать он будет иначе в некоторых похожих

запросах, в зависимости от того, используют они ALL или ANY вместо

EXISTS. Рассмотрим наш предыдущий пример:

SELECT *

FROM Customers

WHERE rating > ANY

( SELECT rating

FROM Customers

WHERE city = 'Rome' );

и еще один пример:

SELECT *

FROM Customers outer

WHERE EXISTS

( SELECT *

FROM Customers inner

WHERE outer.rating > inner.rating

AND inner.city = 'Rome' );

164 ПОНИМАНИЕ SQL

______________________________________________________________________

ГЛ. 13

В общем, эти два запроса будут вести себя одинаково. Но предположим,

что появилось пустое(NULL) значение в столбце rating таблицы Заказчиков:

CNUM CNAME CITY RATING SNUM

2003 Liu SanJose NULL 1002

В варианте с ANY, где оценка Liu выбрана основным запросом, значе-

ние NULL делает предикат неизвестным а строка Liu не выбирается

для вывода. Однако, в варианте с NOT EXISTS когда эта строка выбра-

на основным запросом, значение NULL используется в предикате под-

запроса, делая его неизвестным в каждом случае. Это означает что под-

запрос не будет производить никаких значений, и EXISTS будет непра-

вилен. Это, естественно, делает оператор NOT EXISTS верным. Следова-

тельно, строка Liu будет выбрана для вывода. Это основное расхожде-

ние, в отличие от других типов предикатов, где значение EXISTS незави-

симо от того верно оно или нет - всегда неизвестно.

Все это является аргументом в пользу использования варианта формули-

ровки с ANY.

Мы не считаем что значение NULL является выше чем допустимое значе-

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

более низкого значения.

Соседние файлы в папке ПОНИМАНИЕ SQL