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             L

INNER 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.xINNER JOIN ON a.x = b.x.

Можно ли CROSS JOIN три таблицы?

Да: a CROSS JOIN b CROSS JOIN c. Результат — a × b × c строк.

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

Очень плохая на больших данных. Только для маленьких или generate_series.


Тренируйте SQL — откройте тренажёр с 1500+ вопросами для собесов.