
- •Информационное обеспечение систем управления Построение запросов при работе с базой данных (Учебное пособие)
- •Тестовая база данных
- •Выборка данных. Команда select
- •Синтаксис оператора select
- •Простые варианты поиска данных
- •Упорядочение результата запроса. Предложение order by
- •Использование ключевого слова distinct
- •Предложение where
- •Синтаксис предложения where
- •Использование операторов сравнения
- •Использование варианта between
- •Проверка на присутствие в списке значений (вариант in)
- •Проверка на пустое значение
- •Поиск в строковых столбцах
- •Вариант like
- •Использование логических операций в условиях поиска
- •Порядок выполнения логических операций
- •Преобразование данных при выборке
- •Обобщение Данных с помощью Агрегатных Функций
- •Использование distinct с count
- •Предложение group by
- •Предложение having
- •Соединение таблиц
- •Внутренние соединения (связывание по равенству)
- •Внешние соединения
- •Левое внешнее соединение
- •Правое внешнее соединение
- •Полное внешнее соединение
- •Более сложные примеры соединений
- •Рефлексивное соединение, или самосоединение
- •Использование подзапросов в операторах sql
- •Выбор одного
- •Использование в подзапросе агрегатных функций
- •Связанные подзапросы
- •Использование оператора exists
- •Использование варианта in с подзапросами
- •Использование not exists
- •Объединение запросов
- •Команда union
- •Добавление данных. Команда insert
- •Добавление отдельной строки
- •Добавление группы строк
- •Обновление уже имеющихся данных. Команда update
- •Удаление данных из таблиц. Команда delete
- •Генераторы и их использование
- •Создание генераторов
- •Использование генераторов
- •Увеличение значения генератора
- •Получение значения генератора в приложение
- •Триггер
Соединение таблиц
Вы помните, что в процессе нормализации таблиц вам часто приходилось разделять таблицы на несколько взаимосвязанных таблиц, чтобы устранить избыточность данных. Тогда же я успокоил вас, сказав, что таблицы снова можно будет объединить с помощью операции соединения. Это действительно так.
Соединение таблиц в операторе SELECT является одним из наиболее мощных и элегантных средств реляционных баз данных.
Существует небольшое количество вариантов соединений, JOIN. Соединения задаются в списке имен таблиц:
FROM <ссылка на таблицу> [, <ссылка на таблицу>]...
Здесь не очень удачно названная мною конструкция <ссылка на таблицу> имеет приблизительно такой синтаксис:
<ссылка на таблицу> ::= { <соединяемая таблица> |
<имя таблицы> |
<имя представления> |
<имя процедуры> [(<значение> [,<значение>] ...)]}
[<псевдоним>]
Мы в этом предложении пока только использовали вариант указания имени одной-единственной таблицы. Сейчас начнем рассматривать соединяемые таблицы.
<соединяемая таблица> ::= <ссылка на таблицу> <тип соединения>
<ссылка на таблицу> ON <условия поиска> | (<ссылка на таблицу>)
<тип соединения> ::= [INNER] JOIN
| {LEFT | RIGHT | FULL} OUTER JOIN
Есть внешние (OUTER) левые, правые и полные соединения, а есть внутренние (INNER) соединения. Если вид соединения не указывается, то по умолчанию предполагается внутреннее соединение.
Рассмотрим на примерах использование всех видов соединений
Внутренние соединения (связывание по равенству)
Связывание по равенству используется чаще всего и является, пожалуй, самым полезным типом связывания таблиц. Связывание по равенству называют также внутренним (INNER JOIN). При связывании по равенству таблицы связываются по общим столбцам, которые в каждой из таблиц обычно являются ключевыми. Поскольку в запросе будет присутствовать более одной таблицы, мы должны использовать для столбцов уточнения, задавая перед именем столбца имя таблицы, псевдоним или алиас — см. дальше. Имя таблицы отделятся от имени столбца точкой.
В случае полного внешнего соединения выбираются все соответствующие условию в предложении WHERE строки как левой, так и правой таблиц. Затем между ними устанавливается соответствие, заданное в предложении ON.
Свяжем две таблицы, покажем все аэропорты с указанием города, где аэропорт расположен:xxxi
SELECT * FROM AIRPORT
INNER JOIN CITY ON AIRPORT.AP_CT_CODE = CITY.CT_CODE
Листинг 16. Результат внутреннего объединения таблиц AIROPORT и CITY - список аэропортов с указанием города расположения
AP_CODE |
AP_NAME |
AP_CT_CODE |
CT_CODE |
CT_NAME |
1 |
Домодедово |
1 |
1 |
Москва |
2 |
Внуково |
1 |
1 |
Москва |
3 |
Шереметьево |
1 |
1 |
Москва |
4 |
Быково |
1 |
1 |
Москва |
5 |
Пулково |
2 |
2 |
С. Петербург |
6 |
Савино |
3 |
3 |
Пермь |
7 |
Кольцово |
4 |
4 |
Екатеренбург |
Данные извлекаются из таблиц AIRPORT и CITY, поскольку требуемые данные размещаются частично в одной, а частично в другой таблице. Условие соединения задается после ключевого слова ON. "Главной" таблицей здесь, в левом соединении, является таблица AIRPORT. К каждой выбранной строке этой таблицы присоединяются данные из таблицы CITY, которые удовлетворяют условию в предложении ON. В нашем случае требуется равенство значения столбца AP_CT_CODE из таблицы AIRPORT, который является внешним ключом, значению столбца CT_CODE из таблицы CITY.
Перепишем запрос, для более осмысленного вывода:xxxii
SELECT CITY.CT_NAME AS "Город",
AIRPORT.AP_NAME AS "Аэропорт"
FROM AIRPORT INNER JOIN CITY
ON AIRPORT.AP_CT_CODE = CITY.CT_CODE
ORDER BY CITY.CT_NAME, AIRPORT.AP_NAME
При создании достаточно сложных операторов бывает утомительным набирать перед именами столбцов полные имена таблиц, особенно если эти имена достаточно длинные. По этой причине существует возможность задавать псевдонимы (или алиасы, alias) для имен таблиц. Сравните следующий оператор:xxxiii
SELECT C.CT_NAME AS "Город",
A.AP_NAME AS "Аэропорт"
FROM AIRPORT A INNER JOIN CITY C
ON A.AP_CT_CODE = C.CT_CODE
ORDER BY C.CT_NAME, A.AP_NAME
В предложении FROM мы для таблицы AIRPORT задали псевдоним A, а для таблицы CITY — псевдоним C. Эти псевдонимы мы используем в списке выбора и в условии соединения.
Можно также использовать предложение WHERE. Например, мы можем получить название всех аэропортов находящихся в городе «Москва»xxxiv
SELECT C.CT_NAME AS "Город",
A.AP_NAME AS "Аэропорт"
FROM AIRPORT A INNER JOIN CITY C
ON A.AP_CT_CODE = C.CT_CODE
WHERE C.CT_NAME = 'Москва'
ORDER BY A.AP_NAME
Город |
Аэропорт |
Москва |
Быково |
Москва |
Внуково |
Москва |
Домодедово |
Москва |
Шереметьево |