Оператор ALLработает таким образом, что предикат является верным, если каждое значение, выбранное подзапросом, удовлетворяет условию в предикате внешнего запроса.
Пример 1.Вывести только тех студентов, чьи оценки выше или равны полученным 10/06/1999.
SELECT *
FROM USP
WHERE OCENKA >= ALL
(SELECT OCENKA
FROM USP
WHERE UDATE= 10/06/1999);
Результат запроса:
UNUM OCENCA UDATE SNUM PNUM
---------------------------------------------------------------------------
1001 5 10/06/1999 3412 2001
1005 5 12/06/1999 3416 2004
Как в случае с ANY, допускается использовать EXISTS дляальтернативной формулировки такого же запроса:
SELECT *
FROM USP FIRST
WHERE EXISTS
(SELECT *
FROM USP SECOND
WHERE FIRST. OCENCA>= SECOND/ OCENCA
AND SECOND. UDATE=10/06/1999);
Основное применение ALL находит со знаком неравенства, т.к. предикат может быть верным, если сравнимое значение равно для всех, т.е. все записи, фактически, идентичны.
Например, запрос
SELECT *
FROM USP
WHERE OCENCA= ALL
(SELECT OCENCA
FROM USP
WHERE UDATE = 10/06/1999);
Является допустимым, но вывод будет, только в том случае, если все оценки за 10/06/1999 окажутся идентичными.
ALL гораздо более эффективно используется со знаком неравенства, т.е. с оператором < >. При этом обязательно надо учитывать, что если подзапрос возвращает много различных значений, то это означает неравенство любому результату. Иначе говоря, предикат верен, если данное значение не найдено среди результатов подзапроса.
|
|
Пример 2. Составить запрос, в котором подзапрос выберет все оценки за 10/06/1999.После этого, основной запрос должен вывести все записи с оценкой, не совпадающей ни с одной из них.
SELECT *
FROM USP
WHERE OCENCA <>ALL
(SELECT OCENCA
FROM USP
WHERE UDATE = 10/06/1999);
Результат запроса:
UNUM OCENCA UDATE SNUM PNUM
---------------------------------------------------------------------------
1003 3 10/06/1999 3414 2005
Аналогичный запрос можно сформулировать с использованием оператора NOT IN:
SELECT *
FROM USP
WHERE OCENCA NOT IN
(SELECT OCENCA
FROM USP
WHERE UDATE = 10/06/1999);
Или, используя оператор ANY:
SELECT *
FROM USP
WHERE OCENKA =ANY
(SELECT OCENCA
FROM USP
WHERE UDATE = 10/06/1999);
Во всех случаях, когда допустимый подзапрос не делает вывода, ALL автоматически возвращает значение ИСТИНА, а ANY- ЛОЖЬ.
Когда SQL сравнивает два значения в предикате, одно из которых NULL,результат этого неизвестен. Неизвестный предикат, аналогично неверному, является причиной того, что запись не выбирается, однако работать он будет несколько иначе, в зависимости от того, используется ALL или ANY. Рассмотрим пример с ANY и такой запрос:
SELECT *
FROM USP FIRST
WHERE EXISTS
(SELECT *
FROM USP SECOND
WHERE FIRST. OCENKA>= SECOND. OCENKA
AND SECOND. UDATE = 10/06/1999);
Пусть NULL значений в таблице нет, оба запроса будут вести себяодинаково. Но в случае проявления NULL значение поле OCENKA таблицы успеваемости, в варианте с ANY предиката при обработке этой строки станет неизвестным и вывода для нее не будет в любом случае однако другие строки будут обрабатывается обычным образом. В варианте с EXISTS,
|
|
значение NULL используется в предикате подзапроса, делая его неизвестным в каждом случае, а это означает, что подзапрос не будет производить никаких значений, а запрос не произведет вывода вообще. Это является важным фактором в пользу использования варианта с ANY.
Таким образом, подзапросы не самое простое, что имеется в SQL, однако они являются одним из мощнейших средств этого языка. Как правило, допускается выполнять тот же запрос с запросами несколькими способами, и, в конечном счете, пользователю решать, каким вариантом воспользоваться.