Вы находитесь на странице: 1из 8

Тема: SQL: JOIN - соединение таблиц базы

данных

Рассматриваемые вопросы:
 INNER JOIN (внутреннее соединение)
 LEFT OUTER JOIN (левое внешнее соединение)
 RIGHT OUTER JOIN (правое внешнее соединение)
 Псевдонимы соединяемых таблиц
 JOIN и соединение более двух таблиц
 Написать запросы SQL с JOIN самостоятельно

Оператор языка SQL JOIN предназначен для соединения двух или более
таблиц базы данных по совпадающему условию. Этот оператор существует
только в реляционных базах данных. Именно благодаря JOIN реляционные
базы данных обладают такой мощной функциональностью, которая позволяет
вести не только хранение данных, но и их, хотя бы простейший, анализ с
помощью запросов. Разберём основные нюансы написания SQL-запросов с
оператором JOIN, которые являются общими для всех СУБД (систем
управления базами данных). Для соединения двух таблиц оператор SQL JOIN
имеет следующий синтаксис:

SELECT ИМЕНА_СТОЛБЦОВ (1..N)


FROM ИМЯ_ТАБЛИЦЫ_1 JOIN ИМЯ_ТАБЛИЦЫ_2
ON УСЛОВИЕ

После одного или нескольких звеньев с оператором JOIN может


следовать необязательная секция WHERE или HAVING, в которой, также, как в
простом SELECT-запросе, задаётся условие выборки. Общим для всех СУБД
является то, что в этой конструкции вместо JOIN может быть указано INNER
JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN, CROSS
JOIN (или, как вариант, запятая).

1
INNER JOIN (внутреннее соединение)
Запрос с оператором INNER JOIN предназначен для соединения таблиц и
вывода результирующей таблицы, в которой данные полностью пересекаются
по условию, указанному после ON.

То же самое делает и просто JOIN. Таким образом, слово INNER - не


обязательное.

Пример 1.Создайте базу данных портала объявлений. В ней есть таблица


Категории (категории объявлений) и Рубрики (части, или иначе - рубрики,
которые и относятся к категориям). Например, части Квартиры, Дачи относятся
к категории Недвижимость, а части Автомобили, Мотоциклы - к категории
Транспорт. Эти таблицы с заполненными данными имеют следующий вид.

Рубрики
КодРубрики НазваниеРубрики КодКатегории
1 Квартиры 505
2 Автомашины 205
3 Доски 10
4 Шкафы 30
5 Книги 160
Категории
КодКатегории НазваниеКатегории Цена
10 Стройматериалы 105,00
30 Мебель 77,00
45 Техника 65,00
205 Транспорт 160,00
505 Недвижимость 210,00

Заметим,

что в таблице Рубрики, Книги имеют КодКатегории - ссылку на


категорию, которой нет в таблице Категории,

а в таблице Категории, Техника имеет КодКатегории - первичный ключ,


ссылки на который нет в таблице Рубрики.
2
Требуется соединить данные этих двух таблиц так, чтобы в
результирующей таблице были поля НазваниеРубрики (тбл Рубрики),
КодКатегории (тблКатегория) и Цена (Цена подачи объявления из
тблКатегории) и чтобы данные полностью пересекались по условию.

Условие - совпадение идентификатора категории в таблице Категории и


ссылки на категорию в таблице Рубрики. Для этого пишем следующий запрос:

1) Напишем запрос без учёта соединения таблиц:

SELECT Рубрики.НазваниеРубрики, Категории.КодКатегории, Категории.Цена


FROM Рубрики ,Категории ;

Получим следующий результат: декартово произведение двух таблиц

3
2) Внесем дополнения в наш запрос- условие соединения таблиц:

SELECT Рубрики.НазваниеРубрики, Категории.КодКАтегории,


Категории.Цена
FROM Рубрики INNER JOIN Категории
ON Рубрики.КодКатегории=Категории.КодКатегории;

Результатом выполнения запроса будет следующая таблица:

Запрос2
НазваниеРубрики КодКАтегории Цена
Квартиры 505 210,00
Автомашины 205 160,00
Доски 10 105,00
Шкафы 30 77,00

В результирующей таблице нет Книг, так как эта запись ссылается на


категорию, которой нет в таблице Категории, и Техники, так как эта запись
имеет внешний ключ в таблице Категории, на который нет ссылки в таблице
Рубрики.

LEFT OUTER JOIN (левое внешнее соединение)


Запрос с оператором LEFT OUTER JOIN предназначен для соединения
таблиц и вывода результирующей таблицы, в которой данные полностью
пересекаются по условию, указанному после ON, и дополняются записями из
первой по порядку (левой) таблицы, даже если они не соответствуют условию.
У записей левой таблицы, которые не соответствуют условию, значение
столбца из правой таблицы будет NULL (неопределённым).

Пример 3. База данных и таблицы - те же, что и в примере 1

4
Для получения результирующей таблицы, в которой данные из двух таблиц
полностью пересекаются по условию и дополняются всеми данными из
таблицы Рубрики, которые не соответствуют условию, пишем следующий
запрос:

SELECT Рубрики.НазваниеРубрики, Категории.КодКАтегории,


Категории.Цена
FROM Рубрики LEFT OUTER JOIN Категории
ON Рубрики.КодКатегории=Категории.КодКатегории;

Результатом выполнения запроса будет следующая таблица:

Запрос3
НазваниеРубрики КодКАтегории Цена
Квартиры 505 210,00
Автомашины 205 160,00
Доски 10 105,00
Шкафы 30 77,00
Книги

В результирующей таблице, в отличие от таблицы из примера 1, есть Книги, но


значение столбца Цены у них - NULL, так как эта запись имеет идентификатор
категории, которой нет в таблице Категории.

RIGHT OUTER JOIN (правое внешнее соединение)


Запрос с оператором RIGHT OUTER JOIN предназначен для соединения
таблиц и вывода результирующей таблицы, в которой данные полностью
пересекаются по условию, указанному после ON, и дополняются записями из
второй по порядку (правой) таблицы, даже если они не соответствуют условию.
У записей правой таблицы, которые не соответствуют условию, значение
столбца из левой таблицы будет NULL (неопределённым).

Пример 4. База данных и таблицы - те же, что и в предыдущих примерах

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

SELECT Рубрики.НазваниеРубрики, Категории.КодКатегории,


Категории.Цена
FROM Рубрики RIGHT JOIN Категории ON
Рубрики.КодКатегории=Категории.КодКатегории;

Результатом выполнения запроса будет следующая таблица:

Запрос4
НазваниеРубрики КодКАтегории Цена
Доски 10 105,00
Квартиры 505 210,00
Автомашины 205 160,00
Шкафы 30 77,00
45 65,00

В результирующей таблице, в отличие от таблицы из примера 1, есть запись с


категорией 45 и ценой 65,00, но значение столбца НазваниеРубрики у неё -
NULL, так как эта запись имеет идентификатор категории, на которую нет
ссылок в таблице Рубрики.

Псевдонимы соединяемых таблиц


В предыдущих запросах мы указывали с названиями извлекаемых столбцов из
разных таблиц полные имена этих таблиц. Такие запросы выглядят громоздко:
одно и то же слово повторяется несколько раз. Нельзя ли как-то упростить
конструкцию? Оказывается, можно. Для этого следует использовать
псевдонимы таблиц - их сокращённые имена. Псевдоним может состоять и из
одной буквы. Возможно любое количество букв в псевдониме, главное, чтобы
запрос после сокращения был понятен Вам самим. Общее правило: в секции
запроса, определяющей соединение, то есть вокруг слова JOIN нужно указать
полные имена таблиц, а за каждым именем должен следовать псевдоним
таблицы.

6
Пример 5. Переписать запрос из примера 2 с использованием псевдонимов
соединяемых таблиц.

Запрос будет следующим:

SELECT Р.НазваниеРубрики, К.КодКатегории, К.Цена


FROM Рубрики Р INNER JOIN Категории К
ON Р.КодКатегории = К.КодКатегории;

Хотя во второй строке FROM были даны сокращенные названия таблиц-


псевдонимы, этими сокращенными названиями мы пользуемся и в первой
строке SELECT и в третьей строке ON.

Примечание: AS можно пропускать!!!!

Запрос вернёт то же самое, что и запрос в примере 2, но он гораздо компактнее.

Запрос5
НазваниеРубрики КодКАтегории Цена
Квартиры 505 210,00
Автомашины 205 160,00
Доски 10 105,00
Шкафы 30 77,00

7
Самостоятельно :
1. Разобрать JOIN и соединение более двух таблиц
2. Привести пример БД с тремя (можно более) таблицами.
Внимание!
Как пример, можно рассматривать свою экзаменационную БД.
Но связи между таблицами удалите. Все таблицы в БД должны
быть без привычных связей!!!
3. Создать ШЕСТЬ запросов на соединение таблиц ,так
чтобы были примеры:
- внутреннего соединения,
- левого внешнего соединения,
- правого внешнего соединения таблиц,
- соединение 3-х таблиц!
4. Обязательно использовать псевдонимы столбцов.
5. Примеры должны быть приведены так, чтобы в результате
запроса было чётко видно ЛЕВОЕ соединение, ПРАВОЕ
соединение или ВНУТРЕННЕЕ соединение!