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

В чем разница между CROSS JOIN и FULL JOIN?

2.0 Middle🔥 91 комментариев
#Базы данных (SQL)

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

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

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

Разница между CROSS JOIN и FULL JOIN

Это два совершенно разных типа соединений таблиц, которые используются в разных сценариях.

CROSS JOIN (Декартово произведение)

CROSS JOIN комбинирует каждую строку из первой таблицы с каждой строкой из второй таблицы. Это создаёт декартово произведение.

Синтаксис:

SELECT *
FROM table1
CROSS JOIN table2;

Эквивалентный синтаксис:

SELECT *
FROM table1, table2;

Пример:

Таблица colors:

  • red
  • blue

Таблица sizes:

  • small
  • large

Запрос:

SELECT *
FROM colors
CROSS JOIN sizes;

Результат (4 строки = 2 × 2):

  • red, small
  • red, large
  • blue, small
  • blue, large

Характеристики:

  • Нет условия ON или WHERE
  • Результат: m × n строк (где m строк в table1, n строк в table2)
  • Полезен для создания всех комбинаций значений

FULL JOIN (Полное внешнее соединение)

FULL JOIN (FULL OUTER JOIN) сохраняет все строки из ОБЕИХ таблиц. Если нет совпадения, появляется NULL.

Синтаксис:

SELECT *
FROM table1
FULL OUTER JOIN table2
ON table1.id = table2.table1_id;

Пример:

Таблица users:

  • 1, Alice
  • 2, Bob
  • 3, Charlie

Таблица orders:

  • 101, 1, 500 (Alice)
  • 102, 2, 300 (Bob)
  • 103, 4, 200 (несуществующий пользователь)

Запрос:

SELECT users.id, users.name, orders.amount
FROM users
FULL OUTER JOIN orders ON users.id = orders.user_id;

Результат:

  • 1, Alice, 500
  • 2, Bob, 300
  • 3, Charlie, NULL (нет заказов)
  • NULL, NULL, 200 (заказ от несуществующего пользователя)

Характеристики:

  • Обязателен условие ON
  • Результат: только строки, которые совпадают ИЛИ есть в одной из таблиц
  • Строки без совпадения дополняются NULL

Сравнение

КритерийCROSS JOINFULL JOIN
УсловиеНет (ON не используется)Обязательно (ON условие)
РезультатДекартово произведениеВсе совпадающие + несовпадающие
Количество строкm × nот max(m, n) до m + n
NULL значенияНетДа, для несовпадающих
ИспользованиеСоздание комбинацийПолное слияние данных

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

CROSS JOIN — полезен для:

-- Создание расписания: каждый преподаватель в каждой комнате
SELECT teachers.name, rooms.room_number
FROM teachers
CROSS JOIN rooms;

-- Генерация всех возможных пар студентов для проекта
SELECT s1.name as student1, s2.name as student2
FROM students s1
CROSS JOIN students s2
WHERE s1.id < s2.id;  -- Избегаем дублирования пар

FULL JOIN — полезен для:

-- Поиск несогласованных данных между двумя базами
SELECT *
FROM legacy_users
FULL OUTER JOIN current_users
ON legacy_users.email = current_users.email
WHERE legacy_users.id IS NULL OR current_users.id IS NULL;

-- Получение всех пользователей и их заказов, включая пользователей без заказов
SELECT users.name, orders.amount
FROM users
FULL OUTER JOIN orders ON users.id = orders.user_id
ORDER BY users.name;

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

CROSS JOIN: Дорогой операция!

# Если table1 имеет 1000 строк, table2 имеет 1000 строк
# CROSS JOIN вернёт 1,000,000 строк!
# Это может привести к проблемам с памятью

Оптимизация:

-- Ограничьте результаты
SELECT *
FROM colors
CROSS JOIN sizes
LIMIT 100;

-- Или используйте условие, чтобы сократить комбинации
SELECT *
FROM products p1
CROSS JOIN products p2
WHERE p1.category = p2.category;

FULL JOIN: Производительность зависит от индексов на колонке соединения.

-- Убедитесь, что есть индексы
CREATE INDEX idx_users_id ON users(id);
CREATE INDEX idx_orders_user_id ON orders(user_id);

В Python с SQLAlchemy

from sqlalchemy import select, func
from sqlalchemy.orm import Session

# CROSS JOIN
query = select(Color.name, Size.name).select_from(
    Color
).join(Size, isouter=True, full=True)  # Не совсем правильно для CROSS

# Правильнее
from sqlalchemy import and_
query = select(Color, Size).select_from(Color).cross_join(Size)
result = session.execute(query).all()

# FULL JOIN
query = select(User, Order).join(
    Order, User.id == Order.user_id, isouter=True, full=True
)
result = session.execute(query).all()

Заключение

CROSS JOIN:

  • Создаёт декартово произведение
  • Нет условия соединения
  • Результат: m × n строк
  • Используйте когда нужны все комбинации

FULL JOIN:

  • Сохраняет строки из обеих таблиц
  • Требует условия ON
  • Результат: совпадающие + несовпадающие строки
  • Используйте для полного слияния данных с NULLs

Выбор между ними зависит от вашей задачи: нужны ли вам все комбинации (CROSS) или полное слияние с сохранением несовпадающих данных (FULL)?