Типы SQL joins
Published: 2023-10-08 20:24:35

Очень частый вопрос с собеседования на программиста: **Какие типы SQL joins вы знаете?**
**Ответ**. 
Их 5 типов:
1) **INNER JOIN**
2) **LEFT OUTER JOIN (или просто LEFT JOIN)**
3) **RIGHT OUTER JOIN (или просто RIGHT JOIN)**
4) **FULL OUTER JOIN (или просто FULL JOIN)**
5) **CROSS JOIN**

Рассмотрим их более подробно на примере. Допустим у нас есть две таблицы, которые мы хотим сджойнить:
1) **clients**. Которая содержит информацию о клиентах вашего интернет магазина. В ней содеожится id клиента и его имя:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wy2pikwocmjsagbk194b.png)
2) **orders**. Она содержит информацию о заказах клинтов. Какой клиент (client_id) и на какую сумму был заказ:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ll6hpqk5re3d8e49785t.png)

Давайте теперь сделаем все 5 типов JOINS по client_id и посмотрим какие мы получим результаты:

1) **INNER JOIN**. Он вернет только строки из обоих таблиц, которые удовлетворяют предикату (условию) нашего джойна. Т.е. те строки для которых clients.id = orders.client_id:

```sql
select * from clients c INNER JOIN orders r ON c.id = r.client_id
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6zz7j2o4srx9wocrksp.png)

Как мы видим у нас нет строки с Vanya, т.к. он не делал заказы. Также у нас две строки с Vasya, т.к. он делал два заказа.

На языке множест это соответствует пересечению двух множест: множеству клиентов и заказов.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kvlwamh49fs9853lsdmw.png)

2) **LEFT JOIN**. Результат будет содержать все строки из первой (левой таблицы), если не было найдено соответствущей строки в правой таблице, то поля второй таблицы будут дополнены NULL.

```sql
select * from clients c LEFT OUTER JOIN orders r ON c.id = r.client_id
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rlei4x0y3113vrjhofcj.png)
Как мы видим результат повторяет результат INNER JOIN + содержит строку Vanya дополненую NULL с информацией о заказах.
На языке множеств это выглядит так:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rds85qd6evmq62d9gmk2.png)

3) **RIGHT JOIN**. Аналогично LEFT JOIN, но результат содержит все строки из правой таблицы и дополняется NULL если нет соотвествующей строки в левой таблице.

```sql
select * from clients c RIGHT OUTER JOIN orders r ON c.id = r.client_id
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x1sbc9q874j0hybblbct.png)


На языке множеств:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bi4ykbt09ete0fnp9h4a.png)

4) **FULL OUTER JOIN**. Результат содержит строки, которые заматчились по условию джойна, а также все оставшиеся строки левой таблицы, которые не заматчились с дополненными полями правой таблицы заполенные NULL + оставшиеся строки правой таблицы с дополненными NULL полями левой таблицы.


```sql
select * from clients c FULL OUTER JOIN orders r ON c.id = r.client_id
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bbr6iuue1x4po2ojr2e8.png)




На языке множеств:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qmeqbsvmgtrm0ejfclau.png)

5) **CROSS JOIN**. Сджойнит каждую строку из первой таблицы с каждой строкой из второй таблицы. Т.е если у нас в первой таблице n строк, а во второй m, то результат будет содержать n * m строк.

```sql
select * from clients c CROSS JOIN orders r
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/el1sme3kgeh09qdr4jof.png)