В то время как большинство соединений требуют определенного условия соответствия (предложение ON), CROSS JOIN работает иначе. Он возвращает все возможные комбинации строк из соединяемых таблиц. Этот результат в математике известен как декартово произведение.
CROSS JOIN создает результирующий набор, где количество строк равно произведению количества строк в первой таблице на количество строк во второй таблице. Для сопоставления строк не используется никакое условие; каждая строка таблицы А просто встречается с каждой строкой таблицы Б.
Визуализация:
Таблица A (Цвета) Таблица B (Размеры)
+-----------+ +-----------+
| цвет | | размер |
+-----------+ +-----------+
| Красный | --\ | S |
| Синий | ---|------> | M |
+-----------+ --/ | L |
+-----------+
Результат (Комбинации):
Красный, S
Красный, M
Красный, L
Синий, S
Синий, M
Синий, L
Если в таблице А 2 строки, а в таблице Б 3 строки, результат будет содержать 2 x 3 = 6 строк.
Существует два способа записи декартова произведения:
-- Явный синтаксис
SELECT
table1.column,
table2.column
FROM
table1
CROSS JOIN
table2;
-- Неявный синтаксис через запятую
SELECT
table1.column,
table2.column
FROM
table1,
table2;
Важно понимать: эти способы записи отличаются не только стилем, но и приоритетом операций.
JOIN имеет более высокий приоритет и выполняется в общем ряду с другими JOIN по тексту запроса.JOIN.Из-за этого смешивание запятой и явных JOIN в одном FROM может менять смысл запроса или вообще приводить к ошибке.
Например, такой запрос некорректен:
FROM a, b JOIN c ON (a.x = c.y AND b.z = c.t)
Почему это ошибка:
b JOIN c;a еще нет;a.x в условии ON недопустима.Именно поэтому явный CROSS JOIN обычно предпочтительнее: не потому что он просто «нагляднее», а потому что он лучше согласуется с остальными JOIN и не создает скрытых проблем с приоритетом.
Предупреждение: Будьте крайне осторожны при использовании
CROSS JOINна больших таблицах. Соединение двух таблиц по 1000 строк в каждой даст 1 000 000 строк!
Представьте, что нам нужно создать отчет или сетку, которая показывает все категории фильмов для каждого магазина, даже если в этом магазине сейчас нет фильмов такой категории.
SELECT
s.store_id,
c.name AS category_name
FROM
store AS s
CROSS JOIN
category AS c;
Это создаст список всех категорий для Магазина 1, за которым последует список всех категорий для Магазина 2.
CROSS JOIN часто используется для генерации больших наборов перестановок для тестирования или для построения календарей/расписаний, где нужно сопоставить все временные интервалы со всеми пользователями.
LEFT JOIN это может помочь выявить отсутствующие комбинации в ваших данных.ON (нет условия сопоставления).