приведенное выше соединение. Между прочим, вполне возможно, хотя, может быть, и несколько необычным образом, сформулировать в языке SQL запрос, результатом которого будет декартово произведение. Например:
SELECT S.*, P.*
FROM S, Р;
Результат. Упомянутая выше таблица СР.
Соединение по условию «больше чем»
Выдать все комбинации информации о поставщиках и деталях, таких, что город местонахождения поставщика следует за городом, где хранится деталь, в алфавитном порядке:
SELECT S.*, P.*
FROM S, P
WHERE S.ГОРОД > Р.ГОРОД;
Получим в результате следующую табл. 8.3.
|
|
|
|
|
|
|
|
|
|
Таблица 8.3 |
Соединение по условию «больше чем» |
|
|||||||||
НОМЕР_ |
|
ФАМИЛИЯ |
|
СОСТОЯНИЕ |
|
S.ГОРОД |
||||
ПОСТАВЩИКА |
|
|
|
|
|
|
|
|
|
|
S2 |
|
Джонс |
|
|
10 |
|
|
Париж |
||
S2 |
|
Джонс |
|
|
10 |
|
|
Париж |
||
S2 |
|
Джонс |
|
|
10 |
|
|
Париж |
||
S3 |
|
Блейк |
|
|
30 |
|
|
Париж |
||
S3 |
|
Блейк |
|
|
30 |
|
|
Париж |
||
S3 |
|
Блейк |
|
|
30 |
|
|
Париж |
||
НОМЕР_ |
НАЗВАНИЕ |
|
ЦВЕТ |
|
ВЕС |
|
P.ГОРОД |
|||
ДЕТАЛИ |
|
|
|
|
|
|
|
|
|
|
P1 |
|
Гайка |
|
Красный |
|
12 |
|
|
Лондон |
|
P4 |
|
Винт |
|
Красный |
|
14 |
|
|
Лондон |
|
P6 |
|
Блюм |
|
Красный |
|
19 |
|
|
Лондон |
|
P1 |
|
Гайка |
|
Красный |
|
12 |
|
|
Лондон |
|
P4 |
|
Винт |
|
Красный |
|
14 |
|
|
Лондон |
|
P6 |
|
Блюм |
|
Красный |
|
19 |
|
|
Лондон |
|
256
Соединение с дополнительным условием
Выдать все комбинации информации о поставщиках и информации о деталях, такие, что рассматриваемые поставщики и детали «соразмещены». Опустить при этом поставщиков с состоянием, равным 20:
SELECT S.*, P.*
FROM S, P
WHERE S.ГОРОД = Р.ГОРОД
AND S.СОСТОЯНИЕ != 20;
Результат представлен в табл. 8.4.
Таблица 8.4 Соединение с дополнительным условием
НОМЕР_ |
|
ФАМИЛИЯ |
|
СОСТОЯНИЕ |
|
S.ГОРОД |
|||
ПОСТАВЩИКА |
|
|
|
|
|
|
|
|
|
S2 |
|
Джонс |
|
|
10 |
|
|
Париж |
|
S2 |
|
Джонс |
|
|
10 |
|
|
Париж |
|
S3 |
|
Блейк |
|
|
30 |
|
|
Париж |
|
S3 |
|
Блейк |
|
|
30 |
|
|
Париж |
|
НОМЕР_ |
НАЗВАНИЕ |
|
ЦВЕТ |
ВЕС |
|
P.ГОРОД |
|||
ДЕТАЛИ |
|
|
|
|
|
|
|
|
|
P2 |
|
Болт |
|
Зеленый |
17 |
|
|
Париж |
|
P5 |
Кулачок |
|
Голубой |
12 |
|
|
Париж |
||
P2 |
|
Болт |
|
Зеленый |
17 |
|
|
Париж |
|
P5 |
Кулачок |
|
Голубой |
12 |
|
|
Париж |
||
Выборка специфицированных полей из соединения
Выдать все комбинации номеров поставщиков и номеров деталей, таких, что поставщик и деталь соразмещены:
SELECT S.НОМЕР_ПОСТАВЩИКА, Р.НОМЕР_ДЕТАЛИ
FROM S, P
WHERE S.ГOPOД = Р.ГОРОД;
257
Имеем результат: |
|
НОМЕР_ПОСТАВЩИКА |
НОМЕР_ДЕТАЛИ |
S1 |
P1 |
S1 |
P4 |
S1 |
P6 |
S2 |
P2 |
S2 |
P5 |
S3 |
P2 |
S3 |
P5 |
S4 |
P1 |
S4 |
P4 |
S4 |
P6 |
Соединение трех таблиц
Выдать все пары названий городов, таких, что какойлибо поставщик, находящийся в первом из этих городов, поставляет некоторую деталь, хранимую во втором городе. Например, поставщик S1 поставляет деталь Р1. Поставщик S1 находится в Лондоне, а деталь Р1 хранится также в Лондоне. Поэтому пара городов «Лондон, Лондон» — это пара городов, которая содержится в результате.
SELECT DISTINCT S.ГOPOД, Р.ГОРОД FROM S, SP, P
WHERE S.HOMEP_ПОСТАВЩИКА = SP.HOMEP_ПОСТАВЩИКА
AND SP.HOMEP_ДЕТАЛИ = Р.НОМЕР_ДЕТАЛИ;
Получаем результат: |
|
S.ГОРОД |
P.ГОРОД |
Лондон |
Лондон |
Лондон |
Париж |
Лондон |
Рим |
Париж |
Лондон |
Париж |
Париж |
В качестве упражнения следует установить, какие конкретно комбинации поставщик — деталь порождают каждую из строк результата в этом примере.
258
Соединение таблицы с ней самой
Выдать все пары номеров поставщиков, такие, что образующие их поставщики соразмещены.
SELECT ПЕРВАЯ.НОМЕР_ПОСТАВЩИКА, ВТОРАЯ. НОМЕР_ПОСТАВЩИКА
FROM S ПЕРВАЯ, S ВТОРАЯ
WHERE ПЕРВАЯ.ГОРОД = ВТОРАЯ.ГОРОД;
Нетрудно видеть, что в этом запросе требуется соединение таблицы S с ней самой по соответствию городов. Поэтому таблица S дважды указывается во фразе FROM. Для того чтобы различать эти два ее вхождения, мы вводим в этой фразе два произвольных ее псевдонима, ПЕРВАЯ и ВТОРАЯ, и используем их как явные уточнители во фразах SELECT и WHERE.
Получаем результат:
НОМЕР_ПОСТАВЩИКА НОМЕР_ПОСТАВЩИКА
S1 |
S1 |
S1 |
S4 |
S2 |
S2 |
S2 |
S3 |
S3 |
S2 |
S3 |
S3 |
S4 |
S1 |
S4 |
S4 |
S5 |
S5 |
Мы можем привести в порядок этот результат, расширив следующим образом фразу WHERE:
SELECT ПЕРВАЯ.НОМЕР_ПОСТАВЩИКА, ВТОРАЯ.НОМЕР_ПОСТАВЩИКА
FROM S ПЕРВАЯ, S ВТОРАЯ
WHERE ПЕРВАЯ.ГОРОД = ВТОРАЯ.ГОРОД AND ПЕРВАЯ.НОМЕР_ПОСТАВЩИКА < ВТОРАЯ.НОМЕР_ПОСТАВЩИКА
259
Условие ПЕРВАЯ.НОМЕР_ПОСТАВЩИКА < |
|
|
ВТОРАЯ.НОМЕР_ПОСТАВЩИКА |
дает двоякий |
эффект: |
а) оно исключает пары номеров |
поставщиков вида |
(х, х); |
б) оно гарантирует, что не будут появляться одновременно пары (х, у) и (у, х).
Имеем в результате:
НОМЕР_ПОСТАВЩИКА НОМЕР_ПОСТАВЩИКА
S1 |
S4 |
S2 |
S3 |
Это первый пример, в котором мы видели, что использование синонимов необходимо. Однако введение таких синонимов никогда не будет ошибкой, даже если их использование не необходимо, и иногда они могут помочь в том, чтобы данное предложение стало более ясным.
Упражнения
Все последующие упражнения к данной части основываются на базе данных поставщиков-деталей-изделий. В каждом из них требуется записать предложение SELECT для указанного запроса. Для удобства ниже вновь приводится структура рассматриваемой базы данных:
S (HOMEP_ПОСТАВЩИКА, ФАМИЛИЯ, СОСТОЯНИЕ, ГОРОД)
Р (НОМЕР_ДЕТАЛИ, НАЗВАНИЕ, ЦВЕТ, ВЕС, ГОРОД)
J (HOMEP_ИЗДЕЛИЯ, НАЗВАНИЕ, ГОРОД)
SPJ (HOMEP_ПОСТАВЩИКА, НОМЕР_ДЕТАЛИ, НОМЕР_ИЗДЕЛИЯ, КОЛИЧЕСТВО)
Простые запросы
1.Выдать полный список деталей для всех изделий.
2.Выдать полный список деталей для всех изделий, изготавливаемых в Лондоне.
3. Выдать |
упорядоченный |
список |
номеров |
260