Оператор ALL

Оператор 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, однако они являются одним из мощнейших средств этого языка. Как правило, допускается выполнять тот же запрос с запросами несколькими способами, и, в конечном счете, пользователю решать, каким вариантом воспользоваться.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: