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