Delphi 3 и создание приложений баз данных

       

Внешние соединения


Выше нами были рассмотрены внутренние соединения таблиц базы данных Напомним, что внутренние соединения имеют место, если в предложении WHERE указано условие

<имя столбца таблицы 1> <оператор> <имя столбца таблицы 2>

Например,

SELECT RASHOD.*, TOVARY.ZENA FROM RASHOD, TOVARY

WHERE RASHOD.TOVAR = TOVARY.TOVAR

В этом случае осуществляется декартово произведение таблиц 1 и 2 и из полученного НД отбираются записи, удовлетворяющие условию поиска (RASHOD TOVAR = TOVARY.TOVAR)

Существует также и другой вид соединения таблиц, внешнее соединение. Оно определяется в предложении FROM согласно спецификации SELECT {* | <значение1> [, <значение2> ...1}

FROM <таблица1> <вид соединения> JOIN < таблица2> ON <условие поиска>

Внешнее соединение похоже на внутреннее соединение, но в результирующий НД включаются также записи ведущей таблицы соединения, которые объединяются с пустым множеством записей другой таблицы. Какая из таблиц будет ведущей, определяет вид соединения

• LEFT -

(левое внешнее соединение), когда ведущей является таблица1 (расположенная слева от вида соединения);

RIGHT - (правое внешнее соединение), когда ведущей является таблица1 (расположенная справа от вида соединения);

Пример.

Пусть имеем таблицы

A.P1 А.Р2 В.Р2
а х 1
B х 1
С у 2
d 1
Рис 25.49
A.P1 А.Р2 В.Р2
а х 1
b х 1
с у 2
2
Рис 25.50

Таблица А Таблица В

Р1

Р2

РЗ

а

х

400

b

х

200

с

у

500

d PI Р2 х 1 у 2 z 2

Тогда выполнение оператора SELECT, реализующего внешнее левое соединение,

SELECT A.P1, А.Р2, В.Р2 FROM A LEFT JOIN В ON А.Р2 = В.Р1

приведет к выдаче результирующего НД (рис 25.49):

Пунктиром показаны столбцы ведущей таблицы А. Как видно, для записи таблицы А, где столбец A.P1 имеет значение 'd', нет парных записей в таблице В, для которых удовлетворялось бы условие поиска А.Р2 = В.Р1. Поэтому данная запись таблицы А показана в соединении с пустой записью.

В то же время, выполнение оператора SELECT, реализующего внешнее правое соединение,

SELECT A.P1, А.Р2, В.Р2 FROM A RIGHT JOIN B ON А.Р2 = В.Р1

приведет к выдаче такого результирующего НД (рис 25.50)

Пунктиром показаны столбцы ведущей таблицы В. Как видно, для записи таблицы В, где столбец В.Р1 имеет значение 'z' и столбец В.Р2 имеет значение '2', нет парных записей в таблице А, для которых удовлетворялось бы условие поиска А.Р2= В.Р1. Поэтому данная запись таблицы В показана в соединении с пустой записью.

Пример.

Построить внешнее соединение по таблице RASHOD с таблицей POKUPATELI, т.е. показать покупателя, соответствующего каждому расходу (результат на рис.25.51).

SELECT R.DAT_RASH, R.TOVAR, R.KOLVO, P.POKUP, P.GOROD

FROM RASHOD R LEFT JOIN POKUPATELI P ON R.POKUP = P.POKUP

или

SELECT R.DAT_RASH, R.TOVAR, R.KOLVO, P.POKUP, P.GOROD

FROM POKUPATELI P RIGHT JOIN RASHOD R ON R.POKUP = P.POKUP

DAT_RASH

TOVAR

KOLVO

POKUP

GOROD

10.01.97

Сахар

20

Лира, ТОО

МОСКВА

10.01.97

Сахар

509 10.01.97 Ставрида консерв 3000 Адмирал. АО С-Петербург 10.01.97 Кока-кола 4000 Саяны. ИЧП Москва 10.01.97 Сахар 30 Саяны. ИЧП Москва 20.01.97 Кока-кола 20 20.01.97 Кока-кола 1000 Адмирал, ДО С-Петербург 10.01.97 Кока-кола 100 Адмирал. ДО С-Петербург

Рис. 25.51.

Пример.

Построить внешнее соединение по таблице POKUPATELI с таблицей RASHOD, т.е. показать все расходы по каждому покупателю (результат на рис.25.52).

SELECT P.POKUP, P.GOROD, R.DAT_RASH, R.TOVAR, R.KOLVO

FROM POKUPATELI P LEFT JOIN RASHOD R ON R.POKUP = P.POKUP

или

SELECT P.POKUP, P.GOROD, R.DAT_RASH, R.TOVAR, R.KOLVO

FROM RASHOD R RIGHT JOIN POKUPATELI P ON R.POKUP = P.POKUP

PQKUP

GOROD

DAT_RASH

TOVAR

KOLVO

Лира ТОО

МОСКВА

10.01.97

Сахар

20

Саяны. ИЧП

Москве

10.01.97

Кока-кола

4000

Саяны, ИЧП

Москва

20.01.97

Сахар

30

Адмирал, АО

С.Петербург

10.6l.97

Ставрида консорв,

3000

Адмирал. АО

С-Петербург

20.01.97

Кока-кола

1000

Адмирал. АО

С-Петербург

10.01.97

Кока-кола

100

Геракл

Уфа

Рис. 25.52.



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