РУКОВОДСТВО ПО РЕЛЯЦИОННОЙ СУБД DB2

         

ЗАПРОС, ИСПОЛЬЗУЮЩИЙ EXISTS


Выдать фамилии поставщиков, которые поставляют деталь P2 (та же самая задача, что и в примерах 5.2.1 и 5.2.3).

SELECT                ФАМИЛИЯ

FROM                   S

WHERE                EXISTS

(SELECT *

FROM              SP

WHERE           НОМЕР_ПОСТАВЩИКА=

S.НОМЕР_ПОСТАВЩИКА

AND                НОМЕР_ДЕТАЛИ = 'P2');

Пояснение. EXISTS (существует) представляет здесь квантор существования — понятие, заимствованное из формальной логики. Пусть символ «х» обозначает некоторую произвольную переменную. Тогда в логике предикат с навешенным квантором существования EXISTS х (предикат—зависящий—от—х) принимает значение истина

тогда и только тогда, когда «предикат—зависящий—от—х» имеет значение истина при каком-либо значении переменной х. Предположим, например, что переменная х обозначает любое целое число в диапазоне от 1 до 10. Тогда предикат

EXISTS х (х < 5)

принимает значение истина. Напротив, предикат

EXISTS х (х < 0)

принимает значение ложь.

В языке SQL предикат с квантором существования представляется выражением вида

EXISTS (SELECT * FROM. . .).

Такое выражение считается истинным тогда и только тогда, когда результат вычисления подзапроса, представленного с помощью «SELECT* FROM.. .», является непустым множеством, иными словами, тогда и только тогда, когда существует какая-либо запись в таблице, указанной во фразе FROM подзапроса, которая удовлетворяет условию WHERE этого подзапроса. (На практике этот подзапрос всегда будет коррелированным множеством.)

Вернемся к приведенному выше примеру. Поочередно рассматриваем каждое значение столбца ФАМИЛИЯ и проверяем, является ли для него истинным условие существования. Предположим, что первое значение поля ФАМИЛИЯ — 'Смит'. Тогда соответствующее значение поля НОМЕР_ПОСТАВЩИКА—S1. Является ли пустым множество записей из SP, содержащих НОМЕР_ПОСТАВЩИКА, равный S1, и НОМЕР_ДЕТАЛИ, равный Р2? Если ответ отрицателен, то существует запись в SP с НОМЕРОМ_ПОСТАВЩИКА, равным S1, и номером детали, равным Р2, и, следовательно, 'Смит' должно быть одним из результирующих значений. Аналогично поступаем для каждого из других значений столбца ФАМИЛИЯ.

Хотя этот первый пример только показывает иной способ формулировки запроса для задачи, с которой мы уже умеем справляться в языке SQL (используя либо соединение, либо оператор IN), EXISTS представляет собой одну из наиболее важных возможностей полного языка SQL. Фактически любой запрос, который может быть выражен с использованием IN, может быть альтернативным образом сформулирован также с помощью EXISTS. Однако обратное высказывание несправедливо (см., например, п. 5.3.3 ниже).



Содержание раздела