CROSS JOIN и декартовы произведения
Используйте намеренные перекрёстные объединения для создания комбинаций и избегайте случайных объединений, взрывающих число строк.
«CROSS JOIN и декартовы произведения» — бесплатный урок Coding Interview Prep на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Coding Interview Prep, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Coding Interview Prep содержит 4 уроков всего.
Соединение, которым интервьюеры пытаются вас поймать
CROSS JOIN соединяет каждую строку левой таблицы с каждой строкой правой таблицы. У него нет условия ON. Если в таблице A 4 строки, а в таблице B 3 строки, результат содержит 4 x 3 = 12 строк.
Это называется декартовым произведением. Интервьюеры спрашивают о нём по двум причинам: чтобы проверить, умеете ли вы намеренно создавать комбинации, и чтобы понять, распознаёте ли вы случайное CROSS JOIN, которое резко увеличивает результирующий набор.
Явный синтаксис CROSS JOIN
Современный, удобный для чтения способ записать декартово произведение — использовать явное ключевое слово CROSS JOIN. Обратите внимание: предложение ON отсутствует, поэтому намерение сразу понятно проверяющему код.
Здесь мы сопоставляем каждый размер с каждым цветом, чтобы построить полную матрицу товаров.
SELECT s.size, c.color
FROM sizes s
CROSS JOIN colors c;Старый синтаксис с запятой
Вы всё ещё можете встретить декартовы произведения, записанные с запятой в предложении FROM и без условия соединения. Это устаревший синтаксис ANSI.
Результат в точности тот же, что и у CROSS JOIN, но это опасно: если вы хотели добавить условие соединения и забыли это сделать, вместо ошибки вы молча получите перекрёстное соединение. Предпочитайте явный CROSS JOIN.
-- Same result as CROSS JOIN, but easy to write by accident
SELECT s.size, c.color
FROM sizes s, colors c;Практический пример: создание таблицы размеров
Представьте, что магазин продаёт футболки трёх размеров и четырёх цветов и хочет получить строку для каждого возможного варианта, даже если он ещё не поступил в продажу. Перекрёстное соединение создаёт все 12 сочетаний за один шаг.
Это самый распространённый намеренный случай использования: создание полной сетки вариантов.
SELECT s.size, c.color, 0 AS stock_qty
FROM sizes s
CROSS JOIN colors c
ORDER BY s.size, c.color;Создание календарной сетки
Ещё один классический пример использования CROSS JOIN на собеседованиях: построить плотную сетку, чтобы в ней присутствовало каждое сочетание, даже при отсутствии данных.
Здесь мы сопоставляем каждый магазин с каждой датой, чтобы последующее LEFT JOIN с продажами возвращало по одной строке на магазин и день, заполняя пропуски нулями. Перекрёстное соединение гарантирует, что ни один день ни одного магазина не будет пропущен.
SELECT st.store_id, d.day
FROM stores st
CROSS JOIN calendar d
WHERE d.day BETWEEN DATE '2024-01-01' AND DATE '2024-01-31';Случайное декартово разрастание
Опасность, которую проверяют на собеседованиях: вы соединяете две таблицы, но забываете условие соединения. Вместо ошибки база данных без проблем возвращает каждое сочетание.
Если в orders 100 000 строк, а в customers — 50 000, результатом станут 5 миллиардов строк. Запросы зависают, память переполняется, а числа выглядят сильно завышенными. Распознать эту закономерность при проверке кода — хороший признак.
-- BUG: no join condition between the two tables
SELECT o.order_id, c.name
FROM orders o, customers c;
-- returns COUNT(orders) * COUNT(customers) rowsКак обнаружить случайное перекрёстное соединение
Симптомы, которые от вас хотят услышать на собеседовании:
- Количество строк примерно равно произведению размеров двух таблиц, а не их сумме.
- Агрегатные функции, такие как
SUM, завышены в постоянное число раз. - План запроса показывает вложенный цикл без фильтра соединения.
Исправление почти всегда заключается в добавлении пропущенного равенства ON или WHERE между таблицами.
CROSS JOIN и INNER JOIN с всегда истинным ON
Логически CROSS JOIN идентично INNER JOIN ... ON 1=1. Оба дают полное декартово произведение.
На самом деле внутреннее соединение — это перекрёстное соединение, за которым следует фильтрация по условию ON. Эта мысленная модель объясняет, почему отсутствие условия превращает внутреннее соединение в перекрёстное.
-- These two queries return identical results
SELECT * FROM a CROSS JOIN b;
SELECT * FROM a INNER JOIN b ON 1 = 1;Перекрёстное соединение с таблицей чисел
Мощный приём: выполнить перекрёстное соединение с небольшой таблицей numbers или generate_series, чтобы намеренно размножить строки. Это используется для преобразования одной строки во множество, например для превращения количества в отдельные строки единиц товара.
Здесь каждая строка товара повторяется qty раз: она соединяется с последовательностью, после чего сохраняются числа, не превышающие это количество.
SELECT p.product_id, n.n AS unit_number
FROM products p
CROSS JOIN generate_series(1, 100) AS n(n)
WHERE n.n <= p.qty;Производительность и безопасная практика
Поскольку объём результата растёт мультипликативно, никогда не выполняйте перекрёстное соединение двух больших таблиц. Пусть хотя бы одна сторона будет маленькой: список размеров, небольшой календарь или таблица чисел.
На собеседовании сформулируйте это прямо: «CROSS JOIN безопасен только тогда, когда одна сторона мала и ограничена; в противном случае результат становится неуправляемым». Эта фраза показывает здравую оценку ситуации, а не только знание синтаксиса.
Когда стоит использовать CROSS JOIN
Используйте осознанно CROSS JOIN, когда нужны все сочетания двух наборов:
- Создание матриц вариантов (размер × цвет).
- Уплотнение временных рядов (магазин × день) перед
LEFT JOIN. - Расширение строк с помощью таблицы чисел.
Если вам не нужны все сочетания, почти наверняка следует использовать соединение с условием ON.
Проверка
Проверьте понимание декартовых произведений.
Итоги: CROSS JOIN
Основные выводы:
- CROSS JOIN сопоставляет каждую строку левой таблицы с каждой строкой правой; размер результата равен произведению входных наборов.
- Синтаксис с запятой без условия даёт то же декартово произведение, часто случайно.
- Используйте его намеренно для сеток сочетаний, уплотнения временных рядов и расширения строк через таблицу чисел.
- Внутреннее соединение с пропущенным
ONнезаметно вырождается в перекрёстное соединение — ошибку разрастания, которую так любят интервьюеры.
Часто задаваемые вопросы
Урок «CROSS JOIN и декартовы произведения» бесплатный?
Да — полный текст урока «CROSS JOIN и декартовы произведения» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Coding Interview Prep, подпишись на CoddyKit PRO. Курс Coding Interview Prep содержит 4 уроков всего.
Чему я научусь в уроке «CROSS JOIN и декартовы произведения»?
Используйте намеренные перекрёстные объединения для создания комбинаций и избегайте случайных объединений, взрывающих число строк. Ты практикуешь Coding Interview Prep с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Coding Interview Prep?
Предыдущий опыт не требуется. Coding Interview Prep на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «CROSS JOIN и декартовы произведения»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Coding Interview Prep?
Да. Каждый урок Coding Interview Prep включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- CROSS JOIN и декартовы произведения
- SELF JOIN для иерархий
- Сравнение строк внутри одной таблицы
- Выбор правильного типа объединения