Оператор ALLработает таким образом, что предикат является верным, если каждое значение, выбранное подзапросом, удовлетворяет условию в предикате внешнего запроса.
Пример 1.Вывести только тех студентов, чьи оценки выше или равны полученным 10/06/1999.
Как в случае с ANY,допускается использовать EXISTS дляальтернативной формулировки такого же запроса:
SELECT*
FROMUSP FIRST
WHEREEXISTS
(SELECT*
FROM USP SECOND
WHERE FIRST. OCENCA>= SECOND/ OCENCA
AND SECOND. UDATE=10/06/1999);
Основное применение ALLнаходит со знаком неравенства, т.к. предикат может быть верным, если сравнимое значение равно для всех, т.е. все записи, фактически, идентичны.
Например, запрос
SELECT*
FROMUSP
WHEREOCENCA=ALL
(SELECT OCENCA
FROM USP
WHERE UDATE = 10/06/1999);
Является допустимым, но вывод будет, только в том случае, если все оценки за 10/06/1999 окажутся идентичными.
ALLгораздо более эффективно используется со знаком неравенства, т.е. с оператором < >. При этом обязательно надо учитывать, что если подзапрос возвращает много различных значений, то это означает неравенство любому результату. Иначе говоря, предикат верен, если данное значение не найдено среди результатов подзапроса.
Пример 2. Составить запрос, в котором подзапрос выберет все оценки за 10/06/1999.После этого, основной запрос должен вывести все записи с оценкой, не совпадающей ни с одной из них.
Аналогичный запрос можно сформулировать с использованием оператора NOT IN:
SELECT*
FROMUSP
WHEREOCENCANOT IN
(SELECT OCENCA
FROM USP
WHERE UDATE = 10/06/1999);
Или, используя оператор ANY:
SELECT*
FROMUSP
WHEREOCENKA=ANY
(SELECT OCENCA
FROM USP
WHERE UDATE = 10/06/1999);
Во всех случаях, когда допустимый подзапрос не делает вывода, ALLавтоматически возвращает значение ИСТИНА, а ANY-ЛОЖЬ.
Когда SQL сравнивает два значения в предикате, одно из которых NULL,результат этого неизвестен. Неизвестный предикат, аналогично неверному, является причиной того, что запись не выбирается, однако работать он будет несколько иначе, в зависимости от того, используется ALL или ANY.Рассмотрим пример с ANYи такой запрос:
SELECT*
FROMUSP FIRST
WHEREEXISTS
(SELECT *
FROM USP SECOND
WHERE FIRST. OCENKA>= SECOND. OCENKA
AND SECOND. UDATE = 10/06/1999);
Пусть NULLзначений в таблице нет, оба запроса будут вести себяодинаково. Но в случае проявления NULLзначение поле OCENKA таблицы успеваемости, в варианте с ANYпредиката при обработке этой строки станет неизвестным и вывода для нее не будет в любом случае однако другие строки будут обрабатывается обычным образом. В варианте с EXISTS,
значениеNULLиспользуется в предикате подзапроса, делая его неизвестным в каждом случае, а это означает, что подзапрос не будет производить никаких значений, а запрос не произведет вывода вообще. Это является важным фактором в пользу использования варианта с ANY.
Таким образом, подзапросы не самое простое, что имеется в SQL, однако они являются одним из мощнейших средств этого языка. Как правило, допускается выполнять тот же запрос с запросами несколькими способами, и, в конечном счете, пользователю решать, каким вариантом воспользоваться.