JOIN в SQL простыми словами: INNER и LEFT JOIN с примерами
Как соединить две таблицы в SQL: чем INNER JOIN отличается от LEFT JOIN, зачем условие ON и три ошибки, из-за которых соединение тихо врёт.
JOIN собирает в одной выдаче данные из двух таблиц. В одной таблице лежат покупатели, в другой — заказы, и у каждого заказа записан номер покупателя. JOIN сшивает строки по этому номеру: к заказу приезжает имя того, кто его сделал.
Зачем вообще две таблицы
Можно было бы писать имя покупателя прямо в каждый заказ. Но у одного человека десятки заказов, и при смене фамилии пришлось бы править их все. Поэтому данные раскладывают по таблицам, а связь держат ключом: в заказе хранится только customer_id. Цена такого порядка — чтобы увидеть имя рядом с заказом, таблицы приходится соединять.
INNER JOIN: только пары
Самое частое соединение — внутреннее. Оно оставляет строки, у которых нашлась пара в обеих таблицах:
SELECT c.name, o.order_date, o.status
FROM customers c
JOIN orders o ON o.customer_id = c.id;
Слово INNER можно не писать: просто JOIN — это и есть внутреннее соединение. Покупатель без единого заказа в такой выдаче не появится вовсе, и это важно помнить: отчёт «все покупатели и их заказы» через INNER JOIN молча теряет людей.
LEFT JOIN: все из левой таблицы
Если нужны все покупатели, даже без заказов, берут левое соединение. Оно оставляет каждую строку левой таблицы, а там, где пары нет, подставляет в колонки правой пустоту — NULL:
SELECT c.name, o.id AS order_id
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id;
Отсюда удобный приём: найти тех, у кого нет ни одного заказа, — дописать WHERE o.id IS NULL. Строки без пары как раз и отличаются пустым ключом справа.
Условие ON: по какому столбцу сшивать
После ON пишут, какие значения должны совпасть: номер покупателя в заказе и номер самого покупателя. Короткие имена таблиц — c и o — это псевдонимы: без них пришлось бы писать customers.id и orders.customer_id полностью.
Три ошибки, из-за которых соединение врёт
- Забыли ON. Тогда каждая строка одной таблицы соединится с каждой строкой другой: десять покупателей и сорок заказов дадут четыреста строк.
- Условие на правую таблицу в WHERE.
LEFT JOIN … WHERE o.status = 'доставлен'выбросит покупателей без заказов — у нихstatusпустой, и условие не проходит. Если нужны все покупатели, условие переносят вON. - Сумма после соединения. Когда к одной строке приезжает несколько парных, значения из неё повторяются, и
SUMсчитает их по нескольку раз. Проверка простая: сравнить число строк до соединения и после.
Где потренироваться
Соединения быстрее всего укладываются в руках, а не в голове. В тренажёре SQL запросы проверяются на той же учебной базе магазина, а в курсе SQL с нуля соединениям отведены отдельные уроки — от первого JOIN до поиска строк без пары. Начать можно с урока про WHERE: условия отбора пригодятся в каждом соединении. Если нужно посчитать итоги по соединённым таблицам, пригодится разбор GROUP BY и HAVING.