metBD (1084482), страница 33
Текст из файла (страница 33)
Таблица 50
НОМЕР_ ПОСТАВЩИКА | ФАМИЛИЯ | СОСТОЯНИЕ | S.ГОРОД |
S1 | Смит | 20 | Лондон |
S1 | Смит | 20 | Лондон |
S1 | Смит | 20 | Лондон |
S2 | Джонс | 10 | Париж |
S2 | Джонс | 10 | Париж |
S3 | Блейк | 30 | Париж |
S3 | Блейк | 30 | Париж |
S4 | Кларк | 20 | Лондон |
S4 | Кларк | 20 | Лондон |
S4 | Кларк | 20 | Лондон |
Продолжение таблицы 50
НОМЕР_ ДЕТАЛИ | НАЗВАНИЕ | ЦВЕТ | ВЕС | P.ГОРОД |
P1 | Гайка | Красный | 12 | Лондон |
P4 | Винт | Красный | 14 | Лондон |
P6 | Блюм | Красный | 19 | Лондон |
P2 | Болт | Зеленый | 17 | Париж |
P5 | Кулачок | Голубой | 12 | Париж |
P2 | Болт | Зеленый | 17 | Париж |
P5 | Кулачок | Голубой | 12 | Париж |
P1 | Гайка | Красный | 12 | Лондон |
P4 | Винт | Красный | 14 | Лондон |
P6 | Блюм | Красный | 19 | Лондон |
Пояснение. Из формулировки задачи на естественном языке ясно, что требуемые данные можно получить из двух таблиц — S и Р. Поэтому в формулировке запроса на языке SQL мы, прежде всего, указываем эти две таблицы во фразе FROM, а затем выражаем во фразе WHERE соединение между ними, т. е. тот факт, что значения ГОРОД должны быть равны. Для того чтобы понять, как это делается, представим себе две строки, по одной из каждой таблицы, например строки, показанные ниже:
НОМЕР_ ПОСТАВЩИКА | ФАМИЛИЯ | СОСТОЯНИЕ | ГОРОД |
S1 | Смит | 20 | Л |
равны
НОМЕР_ ДЕТАЛИ | НАЗВАНИЕ | ЦВЕТ | ВЕС | ГОРОД |
P1 | Гайка | Красный | 12 | Лондон |
Из этих двух строк можно видеть, что поставщик S1 и деталь Р1 в действительности «соразмещены». Из таких двух строк будет сформирована строка результата:
НОМЕР_ ПОСТАВЩИКА | ФАМИЛИЯ | СОСТОЯНИЕ | ГОРОД |
S1 | Смит | 20 | Лондон |
НОМЕР_ ДЕТАЛИ | НАЗВАНИЕ | ЦВЕТ | ВЕС | ГОРОД |
P1 | Гайка | Красный | 12 | Лондон |
поскольку они удовлетворяют предикату во фразе WHERE (S.ГОРОД =Р.ГОРОД). Это имеет место и для всех других пар строк, содержащих соответствующие значения ГОРОД. Обратите внимание на то, что поставщик S5, размещающийся в Атенсе, не попадает в результирующую таблицу, так как нет каких-либо деталей, хранимых в этом городе. Подобным же образом результат не содержит детали Р3, хранимой в Риме, ввиду того, что нет поставщиков, размещенных в Риме.
Результат данного запроса называется соединением таблиц S и P по соответствию значений ГОРОД. Термин «соединение» используется также для обозначения операции конструирования такого результата. Условие S.ГОРОД =Р.ГОРОД называется условием соединения или предикатом соединения. В связи с приведенным примером нужно отметить ряд моментов. Одни из них имеют важное значение, другие не настолько существенны.
-
Оба поля в предикате соединения должны быть либо числовыми, либо строками литер. Не обязательно, чтобы их типы данных были идентичны. Однако, по соображениям производительности, это было бы, вообще говоря, неплохо.
-
Необязательно, чтобы поля в предикате соединения имели одинаковые имена, хотя очень часто это будет именно так.
-
Нет необходимости в том, чтобы оператор сравнения в предикате соединения обязательно был равенством, хотя это будет очень часто. В дальнейшем будут приведены примеры такого рода. В случае оператора равенства соединение называют иногда эквисоединением.
-
Фраза WHERE в SELECT-соединении может включать, помимо самого предиката соединения, другие условия.
-
Можно, конечно, предусмотреть в SELECT выборку только специфицированных полей соединения, а не их всех.
-
Выражение
SELECT S.*, P.*
FROM S, P
может быть еще более упрощено:
SELECT *
FROM S, Р
С другой стороны, оно может быть записано и в расширенном виде:
SELECT НОМЕР_ПОСТАВЩИКА, ФАМИЛИЯ, СОСТОЯНИЕ, S.ГОРОД, НОМЕР_ДЕТАЛИ, НАЗВАНИЕ, ЦВЕТ, ВЕС, Р.ГОРОД
FROM S, P
В такой формулировке для S.ГОРОД и Р.ГОРОД во фразе SELECT следует указывать их уточненные имена, как показано в примере, поскольку неуточненное имя ГОРОД было бы двусмысленным.
-
По определению, эквисоединение должно продуцировать результат, содержащий два идентичных столбца. Если исключить один из этих столбцов, то оставшееся называется естественным соединением. Для того чтобы построить естественное соединение таблиц S и Р по городам в SQL, следовало бы записать:
SELECT НОМЕР_ПОСТАВЩИКА, ФАМИЛИЯ, СОСТОЯНИЕ, S.ГОРОД, НОМЕР_ДЕТАЛИ, НАЗВАНИЕ, ЦВЕТ, ВЕС
FROM S, P
WHERE S.ГОРОД = Р.ГОРОД;
Естественное соединение является, вероятно, одной из наиболее полезных форм соединения — в такой степени, что мы часто используем неуточненный термин «соединение» специально для обозначения этого случая.
-
Можно образовывать соединения также и трех, четырех, ... или любого числа таблиц.
-
В табл. 51 рассматривается альтернативный (и полезный) способ, позволяющий представить себе, каким образом концептуально могут конструироваться соединения. Прежде всего, построим декартово произведение таблиц, перечисленных во фразе FROM. Декартово произведение множества, состоящего из n таблиц, — это таблица, содержащая всевозможные строки r, такие, что r является конкатенацией какой-либо строки из первой таблицы, строки из второй таблицы, ... и строки из n-й таблицы.
Таблица 51
НОМЕР_ ПОСТАВЩИКА | ФАМИЛИЯ | СОСТОЯНИЕ | S.ГОРОД |
S1 | Смит | 20 | Лондон |
S1 | Смит | 20 | Лондон |
S1 | Смит | 20 | Лондон |
S1 | Смит | 20 | Лондон |
S1 | Смит | 20 | Лондон |
S1 | Смит | 20 | Лондон |
S2 | Джонс | 10 | Париж |
… | … | … | … |
S5 | Адамс | 30 | Атенс |
Продолжение таблицы 51
НОМЕР_ ДЕТАЛИ | НАЗВАНИЕ | ЦВЕТ | ВЕС | P.ГОРОД |
P1 | Гайка | Красный | 12 | Лондон |
P2 | Болт | Зеленый | 17 | Париж |
P3 | Винт | Голубой | 17 | Рим |
P4 | Винт | Красный | 14 | Лондон |
P5 | Кулачок | Голубой | 12 | Париж |
P6 | Блюм | Красный | 19 | Лондон |
P1 | Гайка | Красный | 12 | Лондон |
… | … | … | … | … |
P6 | Блюм | Красный | 19 | Лондон |
Например, табл. 51 (назовем ее СР) представляет собой декартовым произведением таблиц S и Р (в указанном порядке). Полная таблица СР содержит 5х6=30 строк. Теперь исключим из этого декартова произведения все такие строки, которые не удовлетворяют предикату соединения. То, что останется, является требуемым соединением. В рассматриваемом случае мы исключаем из таблицы СР все те строки, в которых S.ГОРОД не равен Р.ГОРОД. В результате получим в точности приведенное выше соединение. Между прочим, вполне возможно, хотя, может быть, и несколько необычным образом, сформулировать в языке SQL запрос, результатом которого будет декартово произведение. Например:
SELECT S.*, P.*
FROM S, Р;
Результат. Упомянутая выше таблица СР.