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

         

ПРОСТОЕ ЭКВИСОЕДИНЕНИЕ


Выдать все комбинации информации о таких поставщиках и деталях, которые размещены в одном и том же городе (иначе говоря, «соразмещены» — безобразный, но удобный термин):

SELECT                S.*, Р.*

FROM                   S, P

WHERE                S.ГОРОД = Р.ГОРОД;

Заметим, что здесь ссылки на поля во фразе WHERE должны уточняться именами содержащих их таблиц. В результате получим следующую ниже таблицу 1. (Во избежание двусмысленности в этой таблице два столбца ГОРОД показаны явным образом как S.ГОРОД и Р.ГОРОД.)

Таблица 1

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

ФАМИЛИЯ



СОСТОЯНИЕ

S.ГОРОД

S1

S1

S1

S2

S2

S3

S3

S4

S4

S4

Смит

Смит

Смит

Джонс

Джонс

Блейк

Блейк

Кларк

Кларк

Кларк

20

20

20

10

10

30

30

20

20

20

Лондон

Лондон

Лондон

Париж

Париж

Париж

Париж

Лондон

Лондон

Лондон

Продолжение табл. 1

НОМЕР_ДЕТАЛИ

НАЗВАНИЕ

ЦВЕТ

ВЕС

Р.ГОРОД

Р1

Р4

Р6

Р2

Р5

Р2

Р5

Р1

Р4

Р6

Гайка 

Винт

Блюм

Болт

Кулачок

Болт

Кулачок

Гайка

Винт

Блюм

Красный

Красный

Красный

Зеленый

Голубой

Зеленый

Голубой

Красный

Красный

Красный

12

14

19

17

12

17

12

12

14

19

Лондон

Лондон

Лондон

Париж

Париж

Париж

Париж

Лондон

Лондон

Лондон

Пояснение. Из формулировки задачи на естественном языке ясно, что требуемые данные можно получить из двух таблиц — S и Р. Поэтому в формулировке запроса на языке SQL мы прежде всего указываем эти две таблицы во фразе FROM, а затем выражаем во фразе WHERE соединение между ними, т. е. тот факт, что значения ГОРОД должны быть равны. Для того чтобы понять, как это делается, представим себе две строки, по одной из каждой таблицы, например строки, показанные ниже:

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

ФАМИЛИЯ

СОСТОЯНИЕ

S. ГОРОД

равны

S1

Смит

20

Лондон

НОМЕР_ДЕТАЛИ

НАЗВАНИЕ

ЦВЕТ

ВЕС

P. ГОРОД

Р1

Гайка

Красный

12

Лондон

Из этих двух строк можно видеть, что поставщик S1 и деталь Р1 в действительности «соразмещены». Из таких двух строк будет сформирована строка результата:


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

ФАМИЛИЯ

СОСТОЯНИЕ

S. ГОРОД

S1

Смит

20

Лондон

НОМЕР_ДЕТАЛИ

НАЗВАНИЕ

ЦВЕТ

ВЕС

P. ГОРОД

Р1

Гайка

Красный

12

Лондон

поскольку они удовлетворяют предикату во фразе WHERE (S.ГОРОД = Р.ГОРОД). Это имеет место и для всех других пар строк, содержащих соответствующие значения ГОРОД. Обратите внимание на то, что поставщик S5, размещающийся в Атенсе, не попадает в результирующую таблицу, так как нет каких-либо деталей, хранимых в этом городе. Подобным же образом результат не содержит детали РЗ, хранимой в Риме, ввиду того, что нет поставщиков, размещенных в Риме.

Результат данного запроса называется соединением таблиц S и Р по соответствию значений ГОРОД. Термин «соединение» используется также для обозначения операции конструирования такого результата. Условие S.ГОРОД = Р.ГОРОД называется условием соединения или предикатом соединения. В связи с приведенным примером нужно отметить ряд моментов. Одни из них имеют важное значение, другие не настолько существенны.

— Оба поля в предикате соединения должны быть либо числовыми, либо строками литер. Не обязательно, чтобы их типы данных были идентичны. Однако, по соображениям производительности, это было бы, вообще говоря, неплохо.

— Необязательно, чтобы поля в предикате соединения имели одинаковые имена, хотя очень часто это будет именно так.

— Нет необходимости в том, чтобы оператор сравнения в предикате соединения обязательно был равенством, хотя это будет очень часто. В дальнейшем будут приведены примеры такого рода (пример 4.3.2 и последняя часть примера 4.3.6). В случае оператора равенства соединение называют иногда эквисоединением.

— Фраза WHERE в SELECT-соединении может включать, помимо самого предиката соединения, другие условия. Эта возможность иллюстрируется ниже в примере 4.3.3.

— Можно, конечно, предусмотреть в SELECT выборку только специфицированных полей соединения, а не их всех. Эта возможность иллюстрируется ниже в примерах 4.3.4—4.3.6.



— Выражение

SELECT                S.*,P.*

FROM                   S, P

 .  .  .  .  .  .       ;

может быть еще более упрощено:

SELECT                *

FROM                   S,P

.  .  .  .  .  .        ;

С другой стороны, оно может быть записано и в расширенном виде:

SELECT                НОМЕР_ПОСТАВЩИКА, ФАМИЛИЯ, СОСТОЯНИЕ, S.город

НОМЕР_ДЕТАЛИ, НАЗВАНИЕ, ЦВЕТ, ВЕС, Р. ГОРОД

FROM                   S, P

.  .  .  .  .  .        ;

В такой формулировке для S.ГОРОД и Р.ГОРОД во фразе SELECT следует указывать их уточненные имена, как показано в примере, поскольку неуточненное имя ГОРОД было бы двусмысленным. Если Вам нужно освежить в памяти вопросы, касающиеся уточненных имен полей, см. введение к разделу 4.2.

— По определению, эквисоединение должно продуцировать результат, содержащий два идентичных столбца. Если исключить один из этих столбцов, то оставшееся называется естественным соединением. Для того, чтобы построить естественное соединение таблиц S и Р по городам в SQL, следовало бы записать:

SELECT                НОМЕР_ПОСТАВЩИКА, ФАМИЛИЯ, СОСТОЯНИЕ, S.ГОРОД,

НОМЕР_ДЕТАЛИ, НАЗВАНИЕ, ЦВЕТ, ВЕС

FROM                   S, P

WHERE                S.ГОРОД = Р.ГОРОД;

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

— Можно образовывать соединения также и трех, четырех, ... или любого числа таблиц. В примере 4.3.5, приведенном ниже, показано соединение трех таблиц.

Таблица 2

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

ФАМИЛИЯ

СОСТОЯНИЕ

S.ГОРОД

S1

S1

S1

S1

S1

S1

S2

.

.

.

S5

Смит

Смит

Смит

Смит

Смит

Смит

Джонс

.

.

.

Адамc

20

20

20

20

20

20

10

.

.

.

30

Лондон

Лондон

Лондон

Лондон

Лондон

Лондон

Париж

.

.

.

Атенс

Продолжение табл. 2

НОМЕР_ДЕТАЛИ

НАЗВАНИЕ

ЦВЕТ

ВЕС

Р.ГОРОД

Р1

Р2

РЗ

Р4

Р5

Р6

Р1

.

.

.

Р6

Гайка

Болт

Винт

Винт



Кулачок

Блюм

Гайка

.

.

Блюм

Красный

Зеленый

Голубой

Красный

Голубой

Красный

Красный

.

.

.

Красный

12

17

17

14

12

19

12

.

.

.

19

Лондон

Париж

Рим

Лондон

Париж

Лондон

Лондон

.

.

.

Лондон

— В табл. 2 рассматривается альтернативный ( и полезный) способ, позволяющий представить себе, каким образом концептуально могут конструироваться соединения. Прежде всего построим  декартово произведение таблиц, перечисленных во фразе FROM. Декартово произведение множества, состоящего из n таблиц,—  это таблица, содержащая всевозможные строки r, такие, что r  является конкатенацией какой-либо строки из первой таблицы, строки из второй таблицы, ... и строки из n-й таблицы. Например, табл. 2 (назовем ее СР) представляет собой декартовым произведением таблиц S и Р (в указанном порядке). Полная таблица СР содержит 5х6=30 строк. Теперь исключим из этого декартова произведения все такие строки, которые не удовлетворяют предикату соединения. То, что останется, является требуемым соединением В рассматриваемом случае мы исключаем из таблицы СР все те строки, в которых S.ГОРОД не равен Р.ГОРОД. В результате получим в точности приведенное выше соединение. Между прочим, вполне возможно, хотя, может быть, и несколько необычным образом, сформулировать в языке SQL запрос, результатом которого будет декартово произведение. Например:

SELECT S             S.*, P.*

FROM                   S, Р;

Результат. Упомянутая выше таблица СР.


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