INNER JOIN: соединение двух таблиц
Содержание курса
INNER JOIN: какой результат получится
Пусть в customers есть Анна (customer_id=1) и Борис (customer_id=2), а в orders — заказы 10 и 11, оба с customer_id=1. Запрос соединяет строки по равенству ключей:
SELECT c.name, o.order_id
FROM customers AS c
INNER JOIN orders AS o
ON c.customer_id = o.customer_id
ORDER BY o.order_id;Результат — две строки: Анна | 10 и Анна | 11. Бориса в выдаче нет: у него не нашлось заказа. Одна строка клиента может дать несколько строк результата, потому что совпадение проверяется для каждого заказа. Именно поэтому подсчёт клиентов через COUNT(*) после такого соединения считает заказы, а не уникальных людей. Для числа покупателей понадобится COUNT(DISTINCT c.customer_id).
Если нужен список всех клиентов, включая Бориса, используйте LEFT JOIN. Ниже урок подробно объясняет условие ON, псевдонимы и выбор столбцов из обеих таблиц.
В прошлом уроке мы разобрали, как внешний ключ связывает строки двух таблиц на уровне схемы. Теперь научимся использовать эту связь прямо в запросе — соединять таблицы так, чтобы получить данные из обеих сразу.
INNER JOIN: синтаксис ON и механизм совпадения строк
До этого момента каждый запрос работал с одной таблицей. Но данные в реляционной базе намеренно разнесены по разным таблицам: имена клиентов — в customers, их заказы — в orders. Чтобы получить и то и другое в одном результате, нужен JOIN.
Базовый синтаксис:
SELECT *
FROM customers
INNER JOIN orders ON customers.customer_id = orders.customer_id;
После INNER JOIN указывается вторая таблица, а после ON — условие: какие столбцы двух таблиц должны совпасть, чтобы строки объединились. Слово INNER можно опустить — просто JOIN без префикса работает точно так же, это синонимы.
Механизм такой: SQLite берёт каждую строку из customers и ищет в orders строки, у которых customer_id совпадает. Если совпадение нашлось — строки склеиваются в одну строку результата. Если нет — строка из customers в результат не попадает вообще.
Это ключевое свойство INNER JOIN: в результат включаются только строки, для которых нашлась пара в обеих таблицах. Ни «левая», ни «правая» таблица не имеет привилегий — если пары нет с любой стороны, строка отбрасывается.
Отсюда вытекает самый частый сюрприз для новичков: результат содержит меньше строк, чем ожидалось. Клиент есть в customers, но заказов не делал — и в результате JOIN его не будет. Заказ есть в orders, но customer_id там указывает на несуществующего клиента — этот заказ тоже пропадёт. Если видите неожиданно короткий результат, первым делом проверяйте именно это: у каждой ли строки есть пара в другой таблице.

