~={yellow}Основные виды JOIN=~ * INNER JOIN * LEFT OUTER JOIN * RIGHT OUTER JOIN * FULL OUTER JOIN * CROSS JOIN ~={yellow}Создадим таблицы для тестов=~ ```sql 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=~ - это тип соединения таблиц, который возвращает строки, имеющие совпадения в обеих таблицах на основе указанного условия. ```sql 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=~ ```sql 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`, то запрос пришлось бы писать только так: ```sql 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`: ```sql 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; ```