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');
В общем, эти два запроса будут вести себя одинаково. Но предположим, что появилось пустое (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 является выше, чем допустимое значение. Более того, результат будет тот же, если мы будем проверять для более низкого значения.