|
@@ -0,0 +1,109 @@
|
|
|
+~={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;
|
|
|
+```
|