ЗАПРОС, В КОТОРОМ ИСПОЛЬЗУЕТСЯ ИМПЛИКАЦИЯ
Выдать номера поставщиков, поставляющих по крайней мере все те детали, которые поставляются поставщиком S2 (тот же самый запрос, что и в предыдущем примере).
В этом примере иллюстрируется еще одно очень полезное понятие — логическая импликация.
Первоначальную задачу можно перефразировать следующим образом: «Выдать номера поставщиков, скажем, Sx, таких, что ДЛЯ ВСЕХ деталей Ру, если поставщик S2 поставляет деталь Ру, то поставщик Sx поставляет деталь Ру».
Выражение
IF p THENq (ЕСЛИ р ТО q),
где р и q — предикаты, является предикатом логической импликации. Он определяется как эквивалент предиката:
NOT (p) OR q.
Иными словами, импликация «IF p THEN q» (читается также следующим образом: «из р СЛЕДУЕТ q») принимает значение ложь
тогда и только тогда, когда q — ложь,
а р — истина, как показывает приведенная ниже таблица истинности (В таблице Т обозначает «истина» (от англ. true), a F-
«ложь» (от англ.false) .— Примеч. пер.)
Р
q
IF p THEN q
Т
Т
Т
Т
F
F
F
Т
Т
F
F
Т
Многие формулировки задач на обычном языке весьма естественным образом выражаются в терминах логической импликации. Несколько примеров можно найти в конце данной главы среди предлагаемых упражнений. Язык SQL непосредственно не поддерживает импликацию. Но предыдущее определение показывает, каким образом любой содержащий импликацию предикат может быть трансформирован в другой предикат, который ее не содержит. Пусть, например, р представляет собой предикат «Поставщик S2 поставляет деталь Ру», а q — предикат «Поставщик Sx поставляет деталь Ру». Тогда предикат
IF p THEN q
эквивалентен предикату
NOT (поставщик S2 поставляет деталь Ру)
OR (поставщик Sx поставляет деталь Ру);
или в языке SQL:
NOT EXISTS
(SELECT *
FROM SP SPY
WHERE SPY. НОМЕР_ПОСТАВЩИКА = 'S2')
OR EXISTS
(SELECT *
FROM SP SPZ
WHERE SPZ. НОМЕР_ПОСТАВЩИКА = Sx
AND SPZ. НОМЕР_ДЕТАЛИ = SPY. НОМЕР_ДЕТАЛИ)
Следовательно, предикат
FORALL Py (IF p THEN q),
который эквивалентен предикату
NOT EXISTS Py (NOT (IF p THEN q)),
т. е. предикату
NOT EXISTS Py (NOT (NOT (p) OR q)),
может быть записан, таким образом, в виде:
NOT EXISTS Py (p AND NOT (q)),
или в языке SQL:
NOT EXISTS
(SELECT *
FROM SP SPY
WHERE НОМЕР_ПОСТАВЩИКА = 'S2'
AND NOT EXISTS
(SELECT *
FROM SP SPZ
WHERE SPZ.НОМЕР_ПОСТАВЩИКА=Sx
AND SPZ.НОМЕР_ДЕТАЛИ=.SPY.НОМЕР_
ДЕТАЛИ))
Поэтому полный запрос принимает вид:
SELECT DISTINCT НОМЕР_ПОСТАВЩИКА
FROM SP SPX
WHERE NOT EXISTS
(SELECT *
FROM SP SPY
WHERE SPY.НОМЕР_ПОСТАВЩИКА = 'S2'
AND NOT EXISTS
(SELECT *
FROM SP SPZ
WHERE SPZ.НОМЕР_ПОСТАВЩИКА =
SPX. НОМЕР_ПОСТАВЩИКА
AND SPZ. НОМЕР_ДЕТАЛИ =
SPY. НОМЕР_ДЕТАЛИ));
Такой же вид имеет запрос в примере 5.3.4. Таким образом, понятие импликации обеспечивает основу для систематического подхода к определенному классу (весьма сложных) запросов и их преобразованию в эквивалентную форму в языке SQL. Попрактиковаться в таком подходе позволяют упражнения 5.12—5.18 в конце данной главы.