← Назад к вопросам

Как работает INNER JOIN?

1.0 Junior🔥 291 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как работает INNER JOIN

INNER JOIN — это один из наиболее часто используемых типов соединений в SQL, который объединяет две таблицы на основе условия и возвращает только совпадающие строки.

Базовая концепция

INNER JOIN возвращает строки, которые имеют совпадающие значения в обеих таблицах. Если значение есть только в одной таблице — оно не включится в результат.

Визуально это можно представить как пересечение двух множеств (Venn диаграмма):

Таблица A       INNER JOIN       Таблица B
  1 2 3       пересечение      2 3 4
    |   |__________________________|   |
    |_____|              |_____________|___
           Результат: 2 3 (только совпадающие)

Синтаксис

SELECT columns
FROM table1
INNER JOIN table2
  ON table1.column = table2.column
WHERE conditions;

Оба варианта эквивалентны:

-- Вариант 1: явный INNER JOIN
SELECT u.name, o.order_id
FROM users u
INNER JOIN orders o ON u.user_id = o.user_id;

-- Вариант 2: краткий синтаксис (неявный JOIN)
SELECT u.name, o.order_id
FROM users u, orders o
WHERE u.user_id = o.user_id;

Практический пример

Представим две таблицы:

users:

user_id | name      | city
--------|-----------|----------
1       | Иван      | Москва
2       | Мария     | СПб
3       | Петр      | Казань
4       | Анна      | Москва

orders:

order_id | user_id | product      | price
---------|---------|------|-------
101      | 1       | MacBook      | 100000
102      | 1       | iPhone       | 50000
103      | 3       | iPad         | 30000
104      | 5       | AirPods      | 10000

Обратите внимание: user_id=2 и user_id=4 в таблице users не имеют заказов, а user_id=5 в orders не существует в users.

Запрос INNER JOIN:

SELECT u.name, o.order_id, o.product
FROM users u
INNER JOIN orders o ON u.user_id = o.user_id;

Результат:

name  | order_id | product
------|----------|----------
Иван  | 101      | MacBook
Иван  | 102      | iPhone
Петр  | 103      | iPad

Заметьте: Мария и Анна не в результате (нет заказов), и заказ user_id=5 не в результате (юзера нет).

Несколько таблиц

Можно соединять несколько таблиц:

SELECT u.name, o.order_id, p.product_name, c.category
FROM users u
INNER JOIN orders o ON u.user_id = o.user_id
INNER JOIN products p ON o.product_id = p.product_id
INNER JOIN categories c ON p.category_id = c.category_id;

Здесь результат будет содержать только строки, где ВСЕ соединения имеют совпадения.

Условия соединения

Условие может быть не только на равенство:

-- Соединение по диапазону дат
SELECT e.name, p.project_name
FROM employees e
INNER JOIN projects p 
  ON e.department_id = p.department_id
  AND p.start_date >= e.hire_date;

-- Несколько условий
SELECT *
FROM customers c
INNER JOIN accounts a
  ON c.customer_id = a.customer_id
  AND a.status = active;

INNER JOIN vs LEFT/RIGHT/FULL JOIN

INNER JOIN: только совпадающие записи ✓ (пересечение)

LEFT JOIN: все из левой таблицы + совпадающие из правой (левое множество целиком)

RIGHT JOIN: совпадающие из левой + все из правой (правое множество целиком)

FULL OUTER JOIN: все из обеих таблиц (оба множества целиком)

Производительность

Советы по оптимизации:

  • Добавьте индексы на столбцы, используемые в ON: CREATE INDEX idx_user_id ON orders(user_id);
  • Убедитесь, что типы данных в условии соответствуют (int vs varchar замедляет запрос)
  • Фильтруйте данные WHERE после JOIN, не в ON
  • Проверьте план выполнения запроса (EXPLAIN в MySQL/PostgreSQL)

Ошибки новичков

Ошибка 1: Забыть условие ON

-- ❌ Неправильно! Создаст декартово произведение
SELECT * FROM users INNER JOIN orders;

Ошибка 2: Использовать INNER JOIN вместо LEFT JOIN

-- Если нужны все пользователи (даже без заказов) — используй LEFT JOIN
SELECT u.name, COUNT(o.order_id) as order_count
FROM users u
LEFT JOIN orders o ON u.user_id = o.user_id
GROUP BY u.user_id;

Ошибка 3: Неправильные типы данных в условии

-- ❌ Медленно: сравнение строки и числа
FROM users u
INNER JOIN orders o ON u.user_id = o.user_id_str;

-- ✅ Правильно
FROM users u
INNER JOIN orders o ON u.user_id = CAST(o.user_id AS INT);

Вывод

INNER JOIN — это мощный инструмент для получения данных, которые должны существовать в обеих таблицах. Это наиболее часто используемый JOIN, и его правильное применение критично для эффективной работы с базами данных.