Как связать три таблицы
Особенности соединения трёх и более таблиц
На этом уроке мы в основном закрепим навыки использования оператора JOIN для соединения нескольких таблиц базы данных.
Вывод данных не из всех соединяемых таблиц
Мы уже соединяли две и три таблицы и уяснили, что эта операция требуется тогда, когда требуется вывести значения столбцов не из одной, а из нескольких таблиц. Но значения столбцов из некоторых соединяемых таблиц вовсе не требуются в результате. Такие таблицы требуется включать в цепочки соединений, потому что только через их первичные и внешние ключи можно «достучаться» до других таблиц, в которых как раз и содержатся необходимые для результата данные.
Итак, нас ждут увлекательные соединения в цепочки уже не только трёх, а четырёх и пяти таблиц.
Скачать архив со скриптом на SQL для установки этой базы со всеми данными можно по этой ссылке.
Рассмотрим каждую таблицу базы данных и установим, какие данные содержатся в каждом столбце каждой таблицы.
Таблица Reader (Читатель). Содержит данные о читателях медиа (сайтов), которые дали своё согласие на отслеживание их активности в сети. Данные анонимны. В нашей базе представлены 100 читателей, что представляет некоторую уменьшенную модель данных, используемых в реальных исследованиях. Данные были уменьшены во избежание громоздкости выводимых результатов. В таблице содержатся столбцы:
Таблица City (Город) В таблице содержатся столбцы:.
Таблица Visit (Визит) Содержит данные о визитах в интернет в течение 4 недель в пределах одного месяца. В таблице содержатся столбцы:.
Таблица Media (Медиа) Содержит данные о сайтах, на которые заходили читатели в течение 4 недель в пределах одного месяца. В таблице содержатся столбцы:.
Таблица Mconttype (Тип контента медиа) Содержит данные о типах контента сайтов. В таблице содержатся столбцы:.
Таблица Mediatheme (Тема медиа) Содержит данные о темах сайтов. В таблице содержатся столбцы:.
Таблица Advertisment (Реклама) Содержит данные о единицах рекламы, которая показывалась читателям во время визита. В таблице содержатся столбцы:.
Таблица Advconttype (Тип контента рекламы) Содержит данные о типах контента сайтов. В таблице содержатся столбцы:.
Таблица Advtheme (Тема рекламы) Содержит данные о темах рекламы. В таблице содержатся столбцы:.
Пример 1. Вывести темы медиа (сайтов) и соответствующую каждой среднюю длительность просмотра. Отсортировать по возрастанию длительности просмотра.
Запрос для выполнения этого задания должен быть таким:
В результате выполнения этого запроса будет выведена следующая таблица:
Если вы хотите выполнить запросы к базе данных из этого урока на MS SQL Server, но эта СУБД не установлена на вашем компьютере, то ее можно установить, пользуясь инструкцией по этой ссылке .
Должны ли соединяемые таблицы быть «соседями» по запросу?
Работаем с таблицами, показанными на рисунке ниже, кроме таблицы City. Для увеличения рисунка щёлкните по нему левой кнопкой мыши.
Пример 2. Вывести темы медиа (сайты), имеющие число просмотров, большее или равно числу просмотров всех медиа (сайтов), имеющих тип контента «VAT».
А как решается эта задача в целом? Применяем кванторную функцию ALL. И основной запрос, и подзапрос в качестве критерия сравнения содержат число просмотров, определяемое агрегатной функцией COUNT. Следовательно, в основном запросе условие выборки должно быть задано не в секции WHERE, а оператором HAVING. В подзапросе же условие задаётся в секции WHERE. Для сравнения числа просмотров применяем оператор «больше или равно» (>=). Так как основной запрос содержит агрегатную фукнцию, не забываем произвести группировку по столбцу Name таблицы Mediatheme. Оператор группировки GROUP BY размещаем перед условием, заданным оператором HAVING.
Запрос для выполнения этого задания должен быть таким:
В результате выполнения этого запроса будет выведена следующая таблица:
Оператор языка SQL JOIN предназначен для соединения двух или более таблиц базы данных по совпадающему условию. Этот оператор существует только в реляционных базах данных. Именно благодаря JOIN реляционные базы данных обладают такой мощной функциональностью, которая позволяет вести не только хранение данных, но и их, хотя бы простейший, анализ с помощью запросов. Разберём основные нюансы написания SQL-запросов с оператором JOIN, которые являются общими для всех СУБД (систем управления базами данных). Для соединения двух таблиц оператор SQL JOIN имеет следующий синтаксис:
После одного или нескольких звеньев с оператором JOIN может следовать необязательная секция WHERE или HAVING, в которой, также, как в простом SELECT-запросе, задаётся условие выборки. Общим для всех СУБД является то, что в этой конструкции вместо JOIN может быть указано INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN, CROSS JOIN (или, как вариант, запятая).
INNER JOIN (внутреннее соединение)
Запрос с оператором INNER JOIN предназначен для соединения таблиц и вывода результирующей таблицы, в которой данные полностью пересекаются по условию, указанному после ON.
Если вы хотите выполнить запросы к базе данных из этого урока на MS SQL Server, но эта СУБД не установлена на вашем компьютере, то ее можно установить, пользуясь инструкцией по этой ссылке .
Таблицы этой базы данных с заполненными данными имеют следующий вид.
Catnumb | Cat_name | Price |
10 | Стройматериалы | 105,00 |
505 | Недвижимость | 210,00 |
205 | Транспорт | 160,00 |
30 | Мебель | 77,00 |
45 | Техника | 65,00 |
Part_ID | Part | Cat |
1 | Квартиры | 505 |
2 | Автомашины | 205 |
3 | Доски | 10 |
4 | Шкафы | 30 |
5 | Книги | 160 |
Результатом выполнения запроса будет следующая таблица:
Part | Cat | Price |
Квартиры | 505 | 210,00 |
Автомашины | 205 | 160,00 |
Доски | 10 | 105,00 |
Шкафы | 30 | 77,00 |
В результирующей таблице нет Книг, так как эта запись ссылается на категорию, которой нет в таблице Categories, и Техники, так как эта запись имеет внешний ключ в таблице Categories, на который нет ссылки в таблице Parts.
В ряде случаев при соединениях таблиц составить менее громоздкие запросы можно с помощью предиката EXISTS и без использования JOIN.
Написать запросы SQL с JOIN самостоятельно, а затем посмотреть решения
Пример 2. Определить самого востребованного актёра за последние 5 лет.
Оператор JOIN использовать 2 раза. Использовать COUNT(), CURDATE(), LIMIT 1.
Пример 3. Вывести список актеров, которые в одном спектакле играют более одной роли, и количество их ролей.
Оператор JOIN использовать 1 раз. Использовать HAVING, GROUP BY.
Подсказка. Оператор HAVING применяется к числу ролей, подсчитанных агрегатной функцией COUNT.
LEFT OUTER JOIN (левое внешнее соединение)
Запрос с оператором LEFT OUTER JOIN предназначен для соединения таблиц и вывода результирующей таблицы, в которой данные полностью пересекаются по условию, указанному после ON, и дополняются записями из первой по порядку (левой) таблицы, даже если они не соответствуют условию. У записей левой таблицы, которые не соответствуют условию, значение столбца из правой таблицы будет NULL (неопределённым).
Для получения результирующей таблицы, в которой данные из двух таблиц полностью пересекаются по условию и дополняются всеми данными из таблицы Parts, которые не соответствуют условию, пишем следующий запрос:
Результатом выполнения запроса будет следующая таблица:
Part | Cat | Price |
Квартиры | 505 | 210,00 |
Автомашины | 205 | 160,00 |
Доски | 10 | 105,00 |
Шкафы | 30 | 77,00 |
Книги | 160 | NULL |
RIGHT OUTER JOIN (правое внешнее соединение)
Запрос с оператором RIGHT OUTER JOIN предназначен для соединения таблиц и вывода результирующей таблицы, в которой данные полностью пересекаются по условию, указанному после ON, и дополняются записями из второй по порядку (правой) таблицы, даже если они не соответствуют условию. У записей правой таблицы, которые не соответствуют условию, значение столбца из левой таблицы будет NULL (неопределённым).
Для получения результирующей таблицы, в которой данные из двух таблиц полностью пересекаются по условию и дополняются всеми данными из таблицы Categories, которые не соответствуют условию, пишем следующий запрос:
Результатом выполнения запроса будет следующая таблица:
Part | Cat | Price |
Квартиры | 505 | 210,00 |
Автомашины | 205 | 160,00 |
Доски | 10 | 105,00 |
Шкафы | 30 | 77,00 |
NULL | 45 | 65,00 |
FULL OUTER JOIN (полное внешнее соединение)
Запрос с оператором FULL OUTER JOIN предназначен для соединения таблиц и вывода результирующей таблицы, в которой данные полностью пересекаются по условию, указанному после ON, и дополняются записями из первой (левой) и второй (правой) таблиц, даже если они не соответствуют условию. У записей, которые не соответствуют условию, значение столбцов из другой таблицы будет NULL (неопределённым).
Для получения результирующей таблицы, в которой данные из двух таблиц полностью пересекаются по условию и дополняются всеми данными как из таблицы Parts, так и из таблицы Categories, которые не соответствуют условию, пишем следующий запрос:
Результатом выполнения запроса будет следующая таблица:
Part | Cat | Price |
Квартиры | 505 | 210,00 |
Автомашины | 205 | 160,00 |
Доски | 10 | 105,00 |
Шкафы | 30 | 77,00 |
Книги | 160 | NULL |
NULL | 45 | 65,00 |
Псевдонимы соединяемых таблиц
Пример 7. Переписать запрос из примера 1 с использованием псевдонимов соединяемых таблиц.
Запрос будет следующим:
Запрос вернёт то же самое, что и запрос в примере 1, но он гораздо компактнее.
JOIN и соединение более двух таблиц
A_Id | Part_ID | Date_start | Date_end | Text |
21 | 1 | ‘2018-02-11’ | ‘2018-04-20’ | «Продаю. « |
22 | 1 | ‘2018-02-11’ | ‘2018-05-12’ | «Продаю. « |
. | . | . | . | . |
27 | 1 | ‘2018-02-11’ | ‘2018-04-02’ | «Продаю. « |
28 | 2 | ‘2018-02-11’ | ‘2018-04-21’ | «Продаю. « |
29 | 2 | ‘2018-02-11’ | ‘2018-04-02’ | «Продаю. « |
30 | 3 | ‘2018-02-11’ | ‘2018-04-22’ | «Продаю. « |
31 | 4 | ‘2018-02-11’ | ‘2018-05-02’ | «Продаю. « |
32 | 4 | ‘2018-02-11’ | ‘2018-04-13’ | «Продаю. « |
33 | 3 | ‘2018-02-11’ | ‘2018-04-12’ | «Продаю. « |
34 | 4 | ‘2018-02-11’ | ‘2018-04-23’ | «Продаю. « |
Запрос будет следующим:
Cat_name |
Недвижимость |
Транспорт |
CROSS JOIN (перекрестное соединение)
Запрос будет следующим:
Запрос вернёт таблицу из 5 * 5 = 25 строк, фрагмент которой приведён ниже:
Catnumb | Cat_name | Price | Part_ID | Part | Cat |
10 | Стройматериалы | 105,00 | 1 | Квартиры | 505 |
10 | Стройматериалы | 105,00 | 2 | Автомашины | 205 |
10 | Стройматериалы | 105,00 | 3 | Доски | 10 |
10 | Стройматериалы | 105,00 | 4 | Шкафы | 30 |
10 | Стройматериалы | 105,00 | 5 | Книги | 160 |
. | . | . | . | . | . |
45 | Техника | 65,00 | 1 | Квартиры | 505 |
45 | Техника | 65,00 | 2 | Автомашины | 205 |
45 | Техника | 65,00 | 3 | Доски | 10 |
45 | Техника | 65,00 | 4 | Шкафы | 30 |
45 | Техника | 65,00 | 5 | Книги | 160 |
Как видно из примера, если результат такого запроса и имеет какую-либо ценность, то это, возможно, наглядная ценность в некоторых случаях, когда не требуется вывести структурированную информацию, тем более, даже самую простейшую аналитическую выборку. Кстати, можно указать выводимые столбцы из каждой таблицы, но и тогда информационная ценность такого запроса не повысится.
Но для CROSS JOIN можно задать условие соединения! Результат будет совсем иным. При использовании оператора «запятая» вместо явного указания CROSS JOIN условие соединения задаётся не словом ON, а словом WHERE.
Запрос будет следующим:
Запрос вернёт то же самое, что и запрос в примере 1:
Part | Cat | Price |
Квартиры | 505 | 210,00 |
Автомашины | 205 | 160,00 |
Доски | 10 | 105,00 |
Шкафы | 30 | 77,00 |
Как присоединить три таблицы в SQL запросе – Пример в MySQL
Главное меню » Базы данных » Учебное пособие по SQL » Как присоединить три таблицы в SQL запросе – Пример в MySQL
Мы обнаружили, что понимание отношение таблиц в качестве первичного ключа и внешнего ключа помогает облегчить задачу.
SQL Join также является очень популярной темой в SQL и там всегда были некоторые вопросы из соединений, как разница между INNER и OUTER JOIN, например SQL – запрос с JOIN Employee Department и разница между LEFT и RIGHT OUTER JOIN и т.д. Короче говоря это одна из самых важных тем в SQL как из опыта так и из точки зрения цели.
Единственный способ освоить SQL JOIN, это сделать как можно больше упражнений, насколько это возможно. Если бы вы могли решить большинство головоломок SQL из классической книги Джо Селко, SQL Puzzles and Answers, 2nd edition, вы были бы более уверены в работе с SQL JOIN, хоть это быть две, три или четыре таблицы.
Объединение трех таблиц, синтаксис в SQL
Вот общий синтаксис запроса SQL, чтобы присоединить три или более таблиц. Этот SQL-запрос должен работать во всех основных баз данных, например в базе данных MySQL, Oracle, Microsoft SQLServer, Sybase и PostgreSQL:
Вот хорошая схема, которая хорошо показывает, как применять различные типы присоединений, например как работают в SQL inner, left outer, right outer и cross joins:
SQL запрос по присоединению трех таблиц в MySQL
Для того, чтобы лучше понять присоединение 3 таблицы в SQL запросе, давайте рассмотрим пример. Рассмотрим популярный пример Employee и Department. В нашем случае мы использовали таблицу ссылок под названием Register, который связывает или имеет отношение Employee для Department. Первичный ключ таблицы Employee (emp_id) является внешним ключом в Register и аналогичным образом, первичный ключ таблицы Department (dept_id) является внешним ключом в таблице Register.
Если вы хотите понять это лучше, попытайтесь объединить таблицы шаг за шагом. Таким образом, вместо того, чтобы присоединиться 3 таблицы за один раз, сначала соединить 2 таблицы и посмотреть, как будет выглядеть таблица результатов. Это все о том, как присоединить три таблицы в одном запросе SQL в реляционной базе данных. Кстати, в этом примере SQL JOIN, мы использовали ANSI SQL, и он будет работать в другой реляционной базы данных, а также, Oracle, SQL Server, Sybase, PostgreSQL и т.д. Дайте нам знать, если вы сталкивались с какой – либо проблемой во время объединения 3 таблицы запросом JOIN в любой другой базе данных.
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
jtest.ru
HTML, CSS, JavaScript, JQuery, PHP, MySQL
SQL для начинающих. Часть 3
Представляю Вашему вниманию вольный перевод статьи SQL for Beginners Part 3
Сегодня мы продолжаем наше путешествие в мире SQL и реляционных систем управления базами данных. В этой части мы научимся работать с несколькими таблицами связанными между собой. Сначала мы познакомимся с базовыми концепциями, а потом начнем работать с запросами JOIN в SQL.
Предыдущие статьи
Вступление
При проектировании базы данных, здравый смысл подсказывает нам, что мы должны использовать различные таблицы для разных данных. Пример: клиенты, заказы, записи, сообщения и т.д. Так же мы должны иметь взаимосвязи между этими таблицами. Например, клиент имеет заказы, а у заказа есть позиции (товары). Эти взаимосвязи должны быть отражены в базе данных. А также, когда мы получаем данные с помощью SQL, мы должны использовать определенные типы запросов JOIN, чтобы получить нужный результат.
Вот несколько типов отношений в базе данных. Сегодня мы рассмотрим следующие:
Когда данные выбираются из нескольких связанных таблиц, мы будем использовать запрос JOIN. Есть несколько типов присоединения, мы познакомимся с этими:
Также мы изучим предложения ON и USING.
Связь один к одному
Допустим есть таблица покупателей (customers):
Мы можем расположить информацию о адресе покупателя в другой таблице:
Теперь у нас есть связь между таблицами покупателей (Customers) и адресами (Addresses). Если каждый адрес может принадлежать только одному покупателю, то такая связь называется «Один к одному». Имейте ввиду, что такой тип отношений не очень распространен. Наша первоначальная таблица, в которой информация о покупателе и его адресе хранилась вместе, в большинстве случаев работает нормально.
Обратите внимание, что теперь поле с названием «address_id», в таблице покупателей, ссылается на соответствующую запись в таблице адресов. Оно называется внешним ключом (Foreign Key) и используется во всех видах связей в базе. Мы рассмотрим этот вопрос позже в этой статье.
Вот так можно отобразить отношения между покупателями и адресами:
Обратите внимание, что существование данных отношений не обязательно, например, может существовать запись о покупателе без связанной записи о его адресе.
Связь один ко многим и многие к одному
Этот тип отношений наиболее часто встречающийся. Рассмотрим такой сайт интернет магазина:
В этих случаях нам потребуется создать связь «Один ко многим». Пример:
Каждый покупатель может иметь 0 или более заказов. Но каждый заказ может принадлежать только одному покупателю.
Связь многие ко многим
В некоторых случаях требуется многочисленные связи по обе стороны отношений. Например, каждый заказ может содержать множество товаров. И каждый товар может присутствовать во многих заказах.
Для такой связи нам потребуется создать дополнительную таблицу:
Так можно представить этот тип отношений:
Если добавить записи items_orders к диаграмме, то она будет выглядеть так:
Связь с собой
Такой тип используется когда у таблицы должны быть связь с собой. Допустим у Вас есть реферальная программа. Покупатели могут ссылаться на других покупателей на вашем сайте интернет магазина. Таблица может выглядеть так:
Покупатели 102 и 103 ссылаются на покупателя 101.
Этот тип похож на связь «Один ко многим», поскольку один покупатель может ссылаться на несколько покупателей. Это можно представить как древовидную структуру:
Один покупатель может ссылаться на одного покупателя, на нескольких покупателей, или вообще не ссылаться ни на одного.
Если Вы хотите создать связь внутри таблицы «многие ко многим», то потребуется создать дополнительную таблицу, такую же как и в предыдущей части.
Внешние ключи
Пока что мы говорили только о базовых вещах. Пришло время применить полученные знания на практике, используя SQL. В данной часть нам нужно понять, что из себя представляют внешние ключи.
В отношениях, обсуждаемых выше, у нас всегда было поле вида «****_id», которое ссылалось столбец в другой таблице. В нашем примере столбец customer_id, в таблице Orders, является внешним ключом:
В таких базах как MySQL есть два способа создания внешних ключей:
Задать внешний ключ явно
Создадим простую таблицу с покупателями:
Теперь создадим таблицу заказов, которая будет содержать вторичный ключ:
Оба столбца (customers.customer_id и orders.customer_id) должны быть одного типа. Если у первого тип INT, то второй не должен быть типа BIGINT, например.
Пожалуйста, помните, что в MySQL полностью поддерживает внешние ключи только подсистема InnoDB. Другие подсистемы хранения данных позволяют определять внешние ключи без каких либо ошибок. Столбцы с внешними ключами индексируются автоматически, если явно не задать другой индекс.
Без явного объявления
Некоторые таблицы заказов могут быть созданы без явного определения внешнего ключа:
Когда данные получают запросом JOIN, Вы можете использовать столбец как внешний ключ, хотя база данных не знает о этих связях.
Мы подошли к изучению запросов JOIN, которые обсудим далее в статье.
Отображение связей
В данный момент, моей любимой программой для проектирования баз данных и отображения связей является MySQL Workbench.
После того как Вы спроектировали базу данных, ее можно экспортировать в SQL и выполнить на сервере. Это очень удобно при создании больших и сложных баз данных.
Запросы JOIN
Чтобы получить связанные данные из базы данных следует использовать запросы JOIN.
Прежде чем мы начнем, давайте создадим для работы тестовые таблицы и данные.
У нас есть 4 покупателя. У одного из них два заказа, у двоих по одному заказу, и у одного вообще нет заказов. Теперь давайте посмотрим какие виды запросов JOIN мы можем выполнять с этими таблицами.
Cross Join (Перекрестное объединение)
Это вид JOIN запроса по-умолчанию, если не определено условие.
Результатом будет, так называемое, «Декартово объединение» таблиц. Это означает, что каждая строка из первой таблицы сопоставляется с каждой строкой второй таблицы. Т.к. в каждой таблице по 4 строки, мы получили в результате 16 строк.
Ключевое слово JOIN можно заменить на запятую, в этом случае.
Конечно такой результат почти бесполезен. Давайте взглянем на другие виды объединений.
Natural Join (Естественное объединение)
При таком виде запроса JOIN таблицы должны иметь совпадающие, по имени, столбцы. В нашем случае в обеих таблицах должен присутствовать столбец customer_id. MySQL объединит записи только в случае совпадения значений в этих столбцах.
Как Вы можете видеть, в этот раз столбец customer_id отображаются только один раз, потому что движок базы рассматривает этот столбец как общий. Мы видим два заказа Adam’а, и другие два заказа Joe и Sandy. Наконец мы получили некоторую полезную информацию.
Inner Join (Внутреннее объединение)
Если условие объединения не указан, то выполняется внутреннее объединение. В этом случае хорошей идеей будет наличие совпадений по полю customer_id в обеих таблицах. Результат должен быть аналогичен естественному объединению.
Результат почти такой же. Столбец customer_id повторяется два раза, по разу для каждой таблицы. Объясняется это тем, что мы попросили базу сравнить значение по двум столбцам. При этом не знаю, что возвращают одну и туже информацию.
Добавим побольше условий к запросу.
Предложение ON
Прежде чем перейти к другим видам объединяющих запросов, нам нужно рассмотреть предложение ON. Оно служит для вставки условий JOIN в отдельные предложения.
Теперь мы можем различать условия, относящиеся к JOIN и условия в части WHERE. Но еще есть небольшая разница в функционировании. Мы увидим это, когда перейдем к примерам с LEFT JOIN.
Предложение USING
Предложение USING немного похоже на конструкцию ON. Если столбцы в таблицах называется одинаково, можно указать их здесь.
На самом деле это очень похоже на NATURAL JOIN, т.е. объединяющий столбец (customer_id) не повторяется дважды.
Left (Outer) Join (Левое внешнее соединение)
LEFT JOIN это вид внешнего соединения. В следующем запросе, если не найдены совпадения во второй таблице, записи из первой таблице все равно отобразятся.
Хотя у Andy и нет заказов, эта запись все равно отображается. Значение из второй таблицы равно NULL.
Это полезно, когда нужно найти записи, у которых нет связей. Например, мы можем найти всех покупателей, которые ничего не заказывали.
Отметим, что ключевое слово OUTER не обязательно. Вы можете использовать просто LEFT JOIN вместо LEFT OUTER JOIN.
Условия
Теперь давайте посмотрим на запросы с условиями.
Так, что случилось с Andy и Sandy? LEFT JOIN подразумевает, что мы должны получить покупателей, у которых нет заказов. Проблема в том, что условие WHERE скрывает эти результаты. Чтобы получить их, мы можем попытаться включить условие с NULL.
Появился Andy, но нет Sandy. Выглядит неправильно. Для того чтобы получить то, что мы хотим, нужно использовать предложение ON.
Right (Outer) Join (Правое внешнее соединение)
Объединение RIGHT OUTER JOIN работает также, только порядок таблиц меняется на обратный.
На этот раз мы не получили результатов с NULL, потому что каждый заказ имеет сопоставление с записью покупателя. Мы можем поменять порядок таблиц и получим тот же результат, что и с LEFT OUTER JOIN.
Теперь у нас появились значения NULL, потому что таблица покупателей с правой стороны от объединения.
Заключение
Спасибо за чтение статьи. Надеюсь Вам понравилось!