Соединения таблиц: JOIN
Соединяем данные из нескольких таблиц и разбираемся, чем отличаются виды JOIN.
JOIN — операция, которая объединяет строки двух таблиц по условию совпадения, обычно по равенству ключей.
Данные для примеров
Возьмём клиентов и их заказы. Намеренно сделаем так, чтобы у одного клиента не было заказов, а один заказ был «бесхозным» — на этом будут видны различия JOIN-ов.
CREATE TABLE clients (
id INTEGER PRIMARY KEY,
name TEXT
);
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
client_id INTEGER,
amount INTEGER
);
INSERT INTO clients (id, name) VALUES
(1, 'Анна'), (2, 'Борис'), (3, 'Вера');
INSERT INTO orders (id, client_id, amount) VALUES
(1, 1, 500), (2, 1, 300), (3, 2, 800), (4, 99, 100);
-- У Веры (id=3) заказов нет. Заказ 4 ссылается на несуществующего клиента 99.
INNER JOIN — только совпадения
Самый частый. Возвращает строки, где совпадение нашлось в обеих таблицах. Несовпавшие отбрасываются.
SELECT c.name, o.amount
FROM clients c
INNER JOIN orders o ON o.client_id = c.id
ORDER BY c.name, o.amount;
Вывод:
Анна|300 Анна|500 Борис|800
Веры нет (у неё нет заказов), бесхозного заказа 4 тоже нет (нет клиента 99). INNER JOIN оставил только полные пары.
LEFT JOIN — все левые строки
Возвращает все строки левой таблицы, а из правой подставляет совпадения или NULL, если их нет. Идеален для вопроса «покажи всех клиентов, в том числе без заказов».
SELECT c.name, o.amount
FROM clients c
LEFT JOIN orders o ON o.client_id = c.id
ORDER BY c.name;
Вывод:
Анна|300 Анна|500 Борис|800 Вера|
Теперь Вера попала в результат, а в столбце amount у неё пусто (NULL) — заказов нет, но клиент показан.
RIGHT и FULL JOIN
RIGHT JOIN — зеркало LEFT: все строки правой таблицы. FULL JOIN — все строки обеих таблиц, с NULL там, где пары не нашлось.
| JOIN | Что возвращает |
INNER | только совпавшие пары |
LEFT | все левые + совпавшие правые (иначе NULL) |
RIGHT | все правые + совпавшие левые (иначе NULL) |
FULL | все строки обеих таблиц |
Примечание: SQLite-песочница поддерживает RIGHT и FULL JOIN начиная с современных версий, но если ваш движок их не понимает, RIGHT JOIN A B всегда можно переписать как LEFT JOIN B A.
Соединение нескольких таблиц
JOIN-ы можно выстраивать в цепочку: соединить заказы с клиентами, а затем с товарами. Каждый следующий JOIN добавляет свою таблицу по своему условию.
SELECT o.id, c.name, p.title
FROM orders o
JOIN clients c ON c.id = o.client_id
JOIN products p ON p.id = o.product_id;
Итог
INNER JOINоставляет только совпавшие пары — несовпавшие строки исчезают.LEFT JOINсохраняет все левые строки, подставляяNULLпри отсутствии пары справа.RIGHT— зеркалоLEFT,FULL— все строки обеих таблиц; JOIN-ы выстраиваются в цепочку.