LEFT и RIGHT OUTER JOIN.md 5.4 KB

Итак, LEFT JOIN это соединение, при котором возвращаются все строки из левой таблицы и соответствующие им строки из правой таблицы, а если соответствующих строк в правой таблице нет, то данные дополнятся NULL.

select b.name as book_name, a.name as author_name
from book b
left join author a using(author_id)
order by author_name, book_name;

|book_name                    |author_name     |
|-----------------------------|----------------|
|Голова профессора Доуэля     |Александр Беляев|
|Остров погибших кораблей     |Александр Беляев|
|Капитанская дочка            |Александр Пушкин|
|Сказка о рыбаке и рыбке      |Александр Пушкин|
|Дети капитана Гранта         |Жюль Верн       |
|Путешествие к центру Земли   |Жюль Верн       |
|Python. К вершинам мастерства|Лусиану Рамальо |
|Судьба человека              |Михаил Шолохов  |
|Тихий Дон                    |Михаил Шолохов  |
|Тихий Дон. Том 1             |Михаил Шолохов  |
|Тихий Дон. Том 2             |Михаил Шолохов  |
|Простой Python               |                |

FULL OUTER JOIN

Такой запрос объединяет запросы left и right join.

CROSS JOIN

Выполняет декартово произведение двух таблиц, то есть каждая строка из первой таблицы соединяется с каждой строкой из второй таблицы.

SELF JOIN

Это объединение таблицы с самой собой.

Давайте предположим, что у нас книги могут ссылаться друг на друга. Например, в книге «Тихий Дон» два тома. Допустим, что мы хотим, чтобы каждый том был представлен в таблице отдельно, со своей обложкой, описанием и так далее. Это можно сделать вот так:

alter table book add column parent_book_id bigint references book(book_id);

insert into book (name, author_id, category_id, parent_book_id)
select
    'Тихий Дон. Том 1',
    author_id,
    category_id,
    book_id
from book where name='Тихий Дон';

insert into book (name, author_id, category_id, parent_book_id)
select
    'Тихий Дон. Том 2',
    author_id,
    category_id,
    book_id
from book where name='Тихий Дон';

Тогда запрос с SELF JOIN выглядит так:

select b.name as book_name, p.name as parent_book_name
from book b
join book p on b.parent_book_id = p.book_id;

|book_name       |parent_book_name|
|----------------|----------------|
|Тихий Дон. Том 1|Тихий Дон       |
|Тихий Дон. Том 2|Тихий Дон       |

Можно использовать и LEFT JOIN или RIGHT JOIN, зависит от нашей задачи:

select b.name as book_name, p.name as parent_book_name
from book b
left join book p on b.parent_book_id = p.book_id;

|book_name                    |parent_book_name|
|-----------------------------|----------------|
|Тихий Дон                    |                |
|Python. К вершинам мастерства|                |
|Судьба человека              |                |
|Капитанская дочка            |                |
|Сказка о рыбаке и рыбке      |                |
|Голова профессора Доуэля     |                |
|Остров погибших кораблей     |                |
|Путешествие к центру Земли   |                |
|Дети капитана Гранта         |                |
|Простой Python               |                |
|Тихий Дон. Том 1             |Тихий Дон       |
|Тихий Дон. Том 2             |Тихий Дон       |


select b.name as book_name, p.name as parent_book_name
from book b
right join book p on b.parent_book_id = p.book_id;

|book_name       |parent_book_name             |
|----------------|-----------------------------|
|Тихий Дон. Том 1|Тихий Дон                    |
|Тихий Дон. Том 2|Тихий Дон                    |
|                |Тихий Дон. Том 1             |
|                |Тихий Дон. Том 2             |
|                |Простой Python               |
|                |Python. К вершинам мастерства|
|                |Сказка о рыбаке и рыбке      |
|                |Путешествие к центру Земли   |
|                |Голова профессора Доуэля     |
|                |Капитанская дочка            |
|                |Судьба человека              |
|                |Дети капитана Гранта         |
|                |Остров погибших кораблей     |