INNER JOIN.md 6.3 KB

~={yellow}Основные виды JOIN=~

  • INNER JOIN
  • LEFT OUTER JOIN
  • RIGHT OUTER JOIN
  • FULL OUTER JOIN
  • CROSS JOIN

~={yellow}Создадим таблицы для тестов=~

drop table if exists book_category, author, book cascade;

create table author (
	author_id bigint generated always as identity primary key,
	name varchar(150) not null check (length(name) >= 3),
	description text check (length(description) >= 30)
);

create table book_category (
	category_id int generated always as identity primary key,
	name varchar(150) not null check (length(name) >= 2)
);

create table book (
	book_id bigint generated always as identity primary key,
	name varchar(255) not null check (length(name) >= 2),
	author_id bigint references author(author_id),
	description text check (length(description) >= 30),
	cover varchar(255),
	category_id int references book_category(category_id),
	created_at timestamp
);

INSERT INTO book_category ("name") VALUES
('Художественая литература'),
('Литература по программированию'),
('Литература по фотографии');

INSERT INTO author ("name",description) VALUES
('Михаил Шолохов','Великий русский советский писатель, журналист и киносценарист.'),
('Лусиану Рамальо','Автор замечательных книг по языку программирования Python.'),
('Александр Пушкин','Русский поэт, драматург и прозаик, рассматривается как основоположник современного русского литературного языка.'),
('Александр Беляев','Русский писатель-фантаст, один из основоположников советской научно-фантастической литературы.'),
('Жюль Верн','Французский писатель, классик приключенческой литературы, один из основоположников жанра научной фантастики.'),
('Борис Пастернак', 'Один из крупнейших русских поэтов XX века.');

INSERT INTO book ("name",author_id,description,cover,category_id,created_at) VALUES
('Тихий Дон',1,'Одно из наиболее значительных, масштабных и талантливых произведений русскоязычной литературы, принесшее автору Нобелевскую премию.','https://cdn.rroom.io/17558b4d-59dd-4f8e-b2c7-51b0d7da5216.png',1,'2024-01-01 00:00:00'),
('Python. К вершинам мастерства',2,'Лучшая книга по углубленному изучению Python.','https://cdn.rroom.io/2bee8345-a535-4fe3-add9-8db804ea89ae.png',2,'2024-01-02 00:00:00'),
('Судьба человека',1,'Пронзительный рассказ о временах Великой Отечественной войны, одно из первых произведений советской литературы, в котором война показана правдиво и наглядною.','https://cdn.rroom.io/271755e5-046f-4842-85cf-4e22cb17b294.png',1,'2024-01-03 00:00:00'),
('Капитанская дочка',3,NULL,NULL,1,'2024-01-04 00:00:00'),
('Сказка о рыбаке и рыбке',3,NULL,NULL,1,'2024-01-05 00:00:00'),
('Голова профессора Доуэля',4,NULL,NULL,1,'2024-01-06 00:00:00'),
('Остров погибших кораблей',4,NULL,NULL,1,'2024-01-07 00:00:00'),
('Путешествие к центру Земли',5,NULL,NULL,1,'2024-01-08 00:00:00'),
('Дети капитана Гранта',5,NULL,NULL,1,'2024-01-09 00:00:00'),
('Простой Python',NULL,NULL,NULL,NULL,'2024-01-10 00:00:00');

~={magenta}INNER JOIN=~ - это тип соединения таблиц, который возвращает строки, имеющие совпадения в обеих таблицах на основе указанного условия.

select b.name as book_name, a.name as author_name
from book b
inner join author a on b.author_id = a.author_id
order by author_name, book_name;

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

~={yellow}Более короткая запись с использованием using=~

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

То есть вместо on b.author_id = a.author_id можно писать using(author_id). Есть мнение, что это вообще хороший повод называть первичные ключи в таблицах именно так, название сущности, подчеркивание, id, вместо просто id.

То есть если бы в таблице авторов первичный ключ был бы не author_id, а id, то запрос пришлось бы писать только так:

select b.name as book_name, a.name as author_name
from book b
inner join author a on b.author_id = a.id
order by author_name, book_name;

При этом можно записать тот же запрос и в таком синтаксисе, вообще без JOIN:

select b.name as book_name, a.name as author_name
from book b, author a
where b.author_id = a.author_id
order by author_name, book_name;