(SELECT*
FROMUNIVERSITY B
WHEREA.RATING >= B.RATING ANDB.CITY = ‘Москва ’);
При отсутствии в таблицах NULLоба эти запроса ведут себя совершенно одинаково. Пусть теперь в таблице UNIVERSITY есть строка с NULL-значениями в столбце RATING. В версии запроса c ANYв основном запросе, когда выбирается поле RATING с NULL, предикат принимает значение UNKNOWNи строка не включается в состав выходных данных. Во втором же варианте запроса, когда NOT EXISTSвыбирает эту строку в основном запросе, NULL-значение используется в предикате подзапроса, присваивая ему значение UNKNOWN. Поэтому в результате выполнения подзапроса не будет получено ни одного значения и подзапрос примет значение ложь. Это в свою очередь сделает NOT EXISTSистинным, и, следовательно, строка с NULLзначением в поле RATING попадет в выходные данные. По смыслу запроса такой результат является неправильным, так как на самом деле рейтинг университета, описываемого данной строкой может быть и больше рейтинга какого-либо московского университета (он просто неизвестен).
Указанная проблема связана с тем, что значение EXISTSвсегда принимает значения истина или ложь, и никогда – UNKNOWN. Это является доводом для использования в таких случаях оператора ANYв место EXISTS.