INNER JOIN vs CROSS JOIN: разница
Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.
Короткий ответ
- INNER JOIN — соединяет строки по условию (ON). Возвращает только совпадения.
- CROSS JOIN — декартово произведение. Каждая с каждой, без условия.
INNER JOIN — 99% случаев в аналитике. CROSS JOIN — редко, для генерации комбинаций.
Синтаксис
INNER JOIN
SELECT *
FROM users u
INNER JOIN orders o ON o.user_id = u.id;Или просто JOIN — это и есть INNER.
CROSS JOIN
SELECT *
FROM colors c
CROSS JOIN sizes s;
-- альтернативный синтаксис
SELECT * FROM colors, sizes;Пример: Cartesian product
colors: sizes:
red S
green M
blue LINNER JOIN (нужно ON)
-- ОШИБКА: INNER JOIN без условия
SELECT * FROM colors INNER JOIN sizes;CROSS JOIN
SELECT * FROM colors CROSS JOIN sizes;Результат (9 строк = 3 × 3):
red, S
red, M
red, L
green, S
green, M
green, L
blue, S
blue, M
blue, LКогда CROSS JOIN полезен
1. Generate все комбинации
Товар × цвет × размер:
SELECT p.name, c.color, s.size
FROM products p
CROSS JOIN colors c
CROSS JOIN sizes s;2. Build date series
Каждая дата × каждый пользователь:
SELECT u.user_id, d.day
FROM users u
CROSS JOIN generate_series(
DATE '2026-01-01',
DATE '2026-12-31',
INTERVAL '1 day'
) d;3. Test data generation
SELECT
g1.n AS x,
g2.n AS y
FROM generate_series(1, 10) g1(n)
CROSS JOIN generate_series(1, 10) g2(n);
-- 100 строк (x, y) от (1,1) до (10,10)4. Pivot-like операции
Расширение данных для сравнения групп.
Когда CROSS JOIN — ошибка
Часто случается по забывчивости:
-- забыли ON → случайный CROSS JOIN
SELECT * FROM users, orders;
-- users: 10 000, orders: 100 000 → 1 миллиард строкНа миллионах строк → вылетает сервер.
Правило: всегда пишите JOIN с явным ON.
Сравнение
| INNER JOIN | CROSS JOIN | |
|---|---|---|
| Требует ON | да | нет |
| Количество строк | ≤ min(left, right) | left × right |
| Частое использование | часто | редко |
| Риск больших данных | низкий | высокий |
Другие типы JOIN
Для полноты:
| JOIN | Смысл |
|---|---|
| INNER | только совпадения |
| LEFT | все из левого + совпавшие из правого |
| RIGHT | все из правого + совпавшие из левого |
| FULL OUTER | все из обоих |
| CROSS | каждый с каждым |
| SELF | таблица с собой |
CROSS JOIN для generate_series
Классический паттерн — заполнить пропущенные даты:
WITH all_dates AS (
SELECT generate_series(
DATE '2026-01-01',
DATE '2026-12-31',
INTERVAL '1 day'
)::DATE AS day
),
user_activity AS (
SELECT user_id, DATE(event_at) AS day, COUNT(*) AS actions
FROM events
GROUP BY 1, 2
)
SELECT
u.user_id,
d.day,
COALESCE(ua.actions, 0) AS actions
FROM (SELECT DISTINCT user_id FROM events) u
CROSS JOIN all_dates d
LEFT JOIN user_activity ua ON ua.user_id = u.user_id AND ua.day = d.day;Это даст каждому пользователю запись на каждый день (с 0 для неактивных).
На собесе
«Что такое CROSS JOIN?» Декартово произведение двух таблиц. Каждая строка с каждой.
«Когда использовать?» Для генерации комбинаций или всех дат × пользователей.
«Опасность CROSS JOIN?» Exponential blow-up на больших таблицах.
«INNER JOIN без ON эквивалентен CROSS JOIN?» Нет, синтаксически INNER JOIN требует ON. FROM a, b без WHERE — по сути cartesian.
Частые ошибки
1. Cartesian explosion
Забыть условие JOIN → миллиарды строк.
2. CROSS JOIN большое × большое
Нужно осторожно — 10 000 × 10 000 = 100 миллионов. Замедляет.
3. Использовать CROSS для генерации, когда есть лучшие инструменты
generate_series (Postgres), recursive CTE для дат — часто чище.
Связанные темы
FAQ
INNER JOIN и , — это одно и то же?
Функционально да, если есть WHERE с условием. Но INNER JOIN ... ON — читаемее.
CROSS JOIN с WHERE — это INNER JOIN?
Да: CROSS JOIN a WHERE a.x = b.x ≡ INNER JOIN ON a.x = b.x.
Можно ли CROSS JOIN три таблицы?
Да: a CROSS JOIN b CROSS JOIN c. Результат — a × b × c строк.
Производительность CROSS JOIN?
Очень плохая на больших данных. Только для маленьких или generate_series.
Тренируйте SQL — откройте тренажёр с 1500+ вопросами для собесов.