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

ПРОСТОЙ ПОДЗАПРОС


Выдать фамилии поставщиков, которые поставляют деталь Р2.

SELECT                ФАМИЛИЯ

FROM                   S

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

(SELECT                     НОМЕР_ПОСТАВЩИКА

FROM                          SP

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

Результат:

ФАМИЛИЯ

  Смит

  Джонс

  Блейк

  Кларк



Пояснение. При обработке полного запроса система обрабатывает прежде всего вложенный подзапрос. Этот подзапрос возвращает множество номеров поставщиков, которые поставляют деталь P2, а именно множество ('S1', 'S2', 'S3', 'S4'). Поэтому первоначальный запрос эквивалентен следующему простому запросу:

SELECT                ФАМИЛИЯ FROM   S

WHERE                НОМЕР_ПОСТАВЩИКА IN ('S1'.'S2','S3','S4');

и, следовательно, получаем приведенный ранее результат.

Неявное уточнение фамилии в этом примере требует дополнительного обсуждения. Заметим, в частности, что «НОМЕР-ПОСТАВЩИКА» слева от IN неявным образом уточняется именем таблицы S, в то время как «НОМЕР-ПОСТАВЩИКА» в подзапросе неявно уточняется именем таблицы SP. Справедливо следующее общее правило: предполагается, что неуточненное имя поля должно уточняться именем таблицы (или псевдонимом таблицы — см. примеры 5.2.3–5.2.5 ниже), указанным в той фразе FROM, которая является непосредственной частью того же самого запроса или подзапроса. В случае поля НОМЕР-ПОСТАВЩИКА слева от IN этой фразой является «FROM S», а в случае поля НОМЕР-ПОСТАВЩИКА в подзапросе—это фраза «FROM SP». Для большей ясности повторим первоначальный запрос с явно указанными предполагаемыми уточнениями:

SELECT                S. ФАМИЛИЯ

FROM                   S

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

(SELECT         SP. НОМЕР_ПОСТАВЩИКА

FROM              SP

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

Неявные уточнения всегда можно отвергнуть путем задания явных уточнений. Это демонстрируется ниже в примерах 5.2.3–5.2.5.

Прежде чем перейти к нашему следующему примеру подзапроса, необходимо отметить еще один важный момент. Первоначальная задача — «Выдать фамилии поставщиков, которые поставляют деталь P2» — может быть эквивалентным образом выражена как запрос с использованием соединения:

SELECT                S. ФАМИЛИЯ

FROM                   S, SP

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

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

Пояснение.

Соединение S и SP по номерам поставщиков представляет собой таблицу из 12 строк (по одной строке для каждой строки SP), каждая из которых состоит из соответствующей строки SP, дополненной значениями ФАМИЛИЯ, СОСТОЯНИЕ и ГОРОД для поставщика, указываемого значением НОМЕР-ПОСТАВЩИКА в этой строке. Из этих 12 строк только четыре относятся к детали P2. Окончательный результат получается, таким образом, выделением значения ФАМИЛИЯ из этих четырех строк.

Обе формулировки первоначального запроса, одна из которых использует подзапрос, а другая — соединение, в равной степени корректны. Вопрос о том, какой из этих формулировок отдать предпочтение,— исключительно дело вкуса данного пользователя.



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