Урок 14: соединения. Внешнее соединение
Урок 14: Соединения
Внутреннее соединение
| поле INNER JOIN поле ON условие
|
Перекрестное соединение
| поле CROSS JOIN поле
|
Естественное соединение
| поле NATURAL JOIN поле
|
ВНЕШНЕЕ СОЕДИНЕНИЕ
|
Левое внешнее соединение
| поле LEFT JOIN поле ON условие
|
Правое внешнее соединение
| поле RIGHT JOIN поле ON условие
|
В этой серии мы с вами поговорим, как же нам выводить с помощью команды SELECT результаты из нескольких таблиц. Делать это достаточно просто, и для реализации такого вывода используются так называемые соединения. Как вы видите всего достаточно много видов соединений. На самом деле их 6, но т. к. реализации SQL у нас бывают разные (MySQL, MS SQL Server), они в общем-то похожи, но иногда различаются в синтаксисе в реализуемых функциях.
Для начала давайте создадим табличку. Таблицы у нас будут следующие:
Издатель
| И у них будет связка. Связка будет реализовываться по принципу «один ко многим», т. е. издатель может издавать много книг, но одна книга может быть издана одним издателем.
|
Книги
|
mysql> CREATE DATABASE books_db;
| Создадим базу данных
|
mysql> USE books_db;
|
|
mysql> CREATE TABLE publishers
(
publisher_id INT AUTO_INCREMENT PRIMARY KEY,
publisher_name VARCHAR(30) NOT NULL
);
| Создадим таблицу «Издатели»
|
mysql> INSERT INTO publishers VALUES(NULL, 'Все книги');
mysql> INSERT INTO publishers VALUES(NULL, 'Прокачай мозги');
mysql> INSERT INTO publishers VALUES(NULL, 'Мир фантазий');
| Вставим значения в таблицу
|
mysql> CREATE TABLE books
(
book_id INT AUTO_INCREMENT PRIMARY KEY,
book_name VARCHAR(30) NOT NULL,
publisher_id INT,
FOREIGN KEY(publisher_id) REFERENCES publishers(publisher_id)
);
| Создадим таблицу «Книги»
|
mysql> INSERT INTO books VALUES(NULL, 'Магия и кровь', 3);
mysql> INSERT INTO books VALUES(NULL, 'Уникальная вселенная', NULL);
mysql> INSERT INTO books VALUES(NULL, 'Физика просто', 2);
mysql> INSERT INTO books VALUES(NULL, 'Рассказ о цветах', 1);
| Вставим значения в таблицу
|
Итак, мы создали 2 таблицы. Выведем информацию о них
mysql> SELECT * FROM books;
| Книги
| book_id
| book_name
| publisher_id
|
| Магия и кровь
|
|
| Уникальная вселенная
| NULL
|
| Физика просто
|
|
| Рассказ о цветах
|
|
|
mysql> SELECT * FROM publishers;
| Издатели
| publisher_id
| publisher_name
|
| Все книги
|
| Прокачай мозги
|
| Мир фантазий
|
|
У нас получается, чтобы каким-то образом узреть наши внешние ключи и вообще понять, как связана наша таблица, нужно выводить две эти таблички и смотреть. Более того, если вы попытаетесь сделать какие-то объединенные запросы, то вы просто запаритесь это писать. Гораздо удобнее совмещать вывод из двух таблиц сразу. И именно это является темой нашего сегодняшнего урока.
Итак, начнем не с внутреннего соединения, а с перекрестного, т. к. оно является самым редко используемым и никудышным.
Вопрос: Что такое перекрестное соединение?
Ответ: Это означает, что у нас просто берется каждая запись из первой таблицы и сопоставляется с каждой записью во второй, и наоборот.
Давайте посмотрим, как это происходит.
mysql> SELECT b. book_name, p. publisher_name
FROM books b CROSS JOIN publishers p;
| Любая команда соединения, начинается с ключевых слов SELECT и выбора тех таблиц, которые мы используем.
b, p – это псевдонимы
|
book_name
| publisher_name
|
Магия и кровь
| Все книги
|
Магия и кровь
| Прокачай мозги
|
Магия и кровь
| Мир фантазий
|
Уникальная вселенная
| Все книги
|
Уникальная вселенная
| Прокачай мозги
|
Уникальная вселенная
| Мир фантазий
|
Физика просто
| Все книги
|
Физика просто
| Прокачай мозги
|
Физика просто
| Мир фантазий
|
Рассказ о цветах
| Все книги
|
Рассказ о цветах
| Прокачай мозги
|
Рассказ о цветах
| Мир фантазий
|
Рассмотрим естественное соединение:
mysql> SELECT b. book_name, p. publisher_name FROM books b NATURAL JOIN publishers p;
|
book_name
| publisher_name
|
Магия и кровь
| Мир фантазий
|
Физика просто
| Прокачай мозги
|
Рассказ о цветах
| Все книги
|
Мы получили интересную штуку. У нас в таблице books есть поле publisher_id, но и в таблице publishers у нас есть поле publisher_id. Он ищет поля с одним и тем же именем, и соединяет их.
mysql> SELECT * FROM books b NATURAL JOIN publishers p;
|
publisher_id
| book_id
| book_name
| publisher_name
|
|
| Магия и кровь
| Мир фантазий
|
|
| Физика просто
| Прокачай мозги
|
|
| Рассказ о цветах
| Все книги
|
Далее изучим внутреннее соединение – оно комбинирует записи на основании какого-то условия, и задается оно ключевым словом ON.
mysql> SELECT b. book_name, p. publisher_name FROM books b
INNER JOIN publishers p
ON b. publisher_id=p. publisher_id;
| Это эквивалентное внутреннее соединение
т. е. в publisher_name прописаны все издатели, которые относятся к данной книге.
|
book_name
| publisher_name
|
Магия и кровь
| Мир фантазий
|
Физика просто
| Прокачай мозги
|
Рассказ о цветах
| Все книги
|
Таким образом, мы получаем все то же самое, потому что у нас происходит сравнение первичных ключей. Он видим в них равенство, т. е. Магия и кровь – это 3, и он соединяет эту запись, как магия и кровь – мир фантазий, потому что мы указали равенство этих ключей. На самом деле такой тип соединения можно назвать эквивалентом. Вы проверяете на равенство. Чисто теоретически можно организовать проверку на неравенство.
mysql> SELECT b. book_name, p. publisher_name FROM books b
INNER JOIN publishers p
ON b. publisher_id< > p. publisher_id;
| Это неэквивалентное внутреннее соединение
т. е. в publisher_name прописаны все издатели, которые не относятся к данной книге.
|
book_name
| publisher_name
|
Магия и кровь
| Все книги
|
Магия и кровь
| Прокачай мозги
|
Физика просто
| Все книги
|
Физика просто
| Мир фантазий
|
Рассказ о цветах
| Прокачай мозги
|
Рассказ о цветах
| Мир фантазий
|
Вопрос: А почему бы нам не заменить ON на WHERE? Ведь WHERE это вроде как тоже условие.
Ответ: Можно заменить, но дело в том, что ON лучше использовать, потому что вы можете визуально разграничить фильтрацию по внутреннему соединению и фильтрацию по контенту.
Рассмотрим внешние соединения:
Воспользуйтесь поиском по сайту: