Очень подробно про джоины написано тут
Однако, там описаны примеры работы джоина двух таблиц, но не описано что случится если будет участвовать третья таблица, вот об этом мы и поговорим.
Но для начала быстрая напоминалка о LEFT и INNER джоинах.
Допустим есть 2 таблицы alpha и beta.
|
alpha
|
beta
|
CREATE TABLE alpha ( |
CREATE TABLE beta ( |
Запрос c LEFT JOIN вернет все 3 строки из таблицы alpha, объединив их по id с таблицей beta, а недостающие значения заполнит NULL:
SELECT * FROM alpha LEFT JOIN beta USING (id) или SELECT * FROM alpha LEFT JOIN beta ON beta.id = alpha.id
|
|
|
пояснение: показать строки таблицы alpha |
Запрос c INNER JOIN вернет 2 строки c id которые есть в обеих таблицах:
SELECT * FROM alpha INNER JOIN beta ON beta.id = alpha.id
|
|
|
|
|
Теперь добавим еще одну строку с уже существующим id:
3 - INSERT INTO beta (id, nameB) VALUES (3, 'Ship');
|
INNER JOIN:
|
|
LEFT JOIN:
|
|
Как мы видим данные из таблицы alfa появились в третьей строке, лично мое мнение - третья строка не должна появляться при INNER JOIN, такое должно быть только при FULL OUTER JOIN. |
Если мы сделаем INNER JOIN еще одной таблицы, то чтобы понять что произойдет, просто представьте, что у Вас уже есть таблица из двух таблиц и Вы просто добавляете к ней еще одну таблицу.
Например таблица
|
gamma
|
CREATE TABLE gamma ( |
В итоге, если мы сделаем запрос:
SELECT *
FROM alpha
INNER JOIN beta ON beta.id = alpha.id
INNER JOIN gamma ON gamma.id = beta.id
То в ответе получим ноль строк, потому что:
Различие указания вариантов условий при LEFT JOIN
Создадим еще одну таблицу omega:
|
CREATE TABLE omega ( |
|
INSERT INTO omega(id, z, nameO) VALUES |
А теперь выполним 2 казалось бы одинаковых запроса:
|
SELECT * FROM alpha |
SELECT * FROM alpha |
|||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||
| WHERE указывает какие строки показать (срабатывает после JOIN-a) |
AND указывает какие строки присоединить (срабатывает во время JOIN-a) |
Как видите, условия вроде идентичны, но результат получается совершенно разным.
p.s. имейте ввиду, что в этой статье столбец id уникален в рамках своей таблицы. Т.е. если в Ваших таблицах столбец id не уникален, то результаты запросов будут совершенно иными.
Возможно ниже изложенное - тема отдельной статьи, но хочется поделиться информацией о всех операциях горизонтального соединения данных.
Есть пять типов соединения:
| Краткий синтаксис | Полный синтаксис | Описание (Это не всегда всем сразу понятно. Так что, если не понятно, то просто вернитесь сюда после рассмотрения примеров.) |
|---|---|---|
| JOIN | INNER JOIN | Из строк левой_таблицы и правой_таблицы объединяются и возвращаются только те строки, по которым выполняются условия_соединения. |
| LEFT JOIN | LEFT OUTER JOIN | Возвращаются все строки левой_таблицы (ключевое слово LEFT). Данными правой_таблицы дополняются только те строки левой_таблицы, для которых выполняются условия_соединения. Для недостающих данных вместо строк правой_таблицы вставляются NULL-значения. |
| RIGHT JOIN | RIGHT OUTER JOIN | Возвращаются все строки правой_таблицы (ключевое слово RIGHT). Данными левой_таблицы дополняются только те строки правой_таблицы, для которых выполняются условия_соединения. Для недостающих данных вместо строк левой_таблицы вставляются NULL-значения. |
| FULL JOIN | FULL OUTER JOIN | Возвращаются все строки левой_таблицы и правой_таблицы. Если для строк левой_таблицы и правой_таблицы выполняются условия_соединения, то они объединяются в одну строку. Для строк, для которых не выполняются условия_соединения, NULL-значения вставляются на место левой_таблицы, либо на место правой_таблицы, в зависимости от того данных какой таблицы в строке не имеется. |
| CROSS JOIN | - | Объединение каждой строки левой_таблицы со всеми строками правой_таблицы. Этот вид соединения иногда называют декартовым произведением. |
Как видно из таблицы полный синтаксис от краткого отличается только наличием слов INNER или OUTER.
Лично я всегда при написании запросов использую только краткий синтаксис, по той причине:
А на последок, диаграмма, поясняющая работу JOIN-ов:

Источники: 1