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


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


Выше нами были рассмотрены внутренние соединения таблиц базы данных Напомним, что внутренние соединения имеют место, если в предложении 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.




Начало  Назад  Вперед



Книжный магазин