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

SQL запрос с JOIN

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

Условие

Даны таблицы:

  • users (id, name)
  • orders (id, user_id, product_id, amount)
  • products (id, name, price)

Напишите SQL запрос, который выводит имя пользователя, название продукта и сумму заказа для всех заказов.

Ожидаемый результат

user_name, product_name, amount

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

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

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

Решение

Понимание задачи

Необходимо связать три таблицы через JOIN для получения информации о пользователях, их заказах и продуктах в одном результирующем наборе данных.

SQL Запрос

SELECT 
    u.name AS user_name,
    p.name AS product_name,
    o.amount
FROM orders o
JOIN users u ON o.user_id = u.id
JOIN products p ON o.product_id = p.id
ORDER BY u.name, p.name;

Разбор запроса

Структура JOIN:

  1. Начинаем с таблицы orders — это центральная таблица, которая содержит внешние ключи на users и products
  2. JOIN users: связываем заказы с пользователями через o.user_id = u.id
  3. JOIN products: связываем заказы с продуктами через o.product_id = p.id

Выбор INNER JOIN:

  • INNER JOIN возвращает только записи, которые есть во всех трёх таблицах
  • Это правильный выбор, так как каждый заказ должен иметь пользователя и продукт
  • Если бы были NULL значения, они не выводились бы

Сортировка:

  • ORDER BY добавлена для удобства просмотра (по имени пользователя, затем по названию продукта)
  • Если сортировка не требуется, строку можно удалить

Альтернативные варианты

С явным указанием INNER JOIN:

SELECT 
    u.name AS user_name,
    p.name AS product_name,
    o.amount
FROM orders o
INNER JOIN users u ON o.user_id = u.id
INNER JOIN products p ON o.product_id = p.id;

Если нужно включить заказы без пользователя или продукта (LEFT JOIN):

SELECT 
    u.name AS user_name,
    p.name AS product_name,
    o.amount
FROM orders o
LEFT JOIN users u ON o.user_id = u.id
LEFT JOIN products p ON o.product_id = p.id;

Оптимизация и Best Practices

1. Алиасы таблиц: использование u, o, p сокращает текст запроса и улучшает читаемость

2. Порядок выполнения JOIN:

  • SQL оптимизатор выберет оптимальный порядок выполнения JOIN
  • Писать нужно логически, а не с точки зрения производительности

3. Индексы:

  • Убедитесь, что есть индексы на orders.user_id и orders.product_id
  • Это критично для производительности при больших объёмах данных
CREATE INDEX idx_orders_user_id ON orders(user_id);
CREATE INDEX idx_orders_product_id ON orders(product_id);

4. Предикаты (WHERE): если нужны только определённые заказы, добавить условие:

WHERE o.amount > 0 AND u.name IS NOT NULL

Объяснение для QA

Для тестирования этого запроса:

  1. Проверить корректность данных — все user_id из таблицы orders должны существовать в users
  2. Проверить полноту — количество строк результата должно равняться количеству строк в orders
  3. Проверить значения — каждая строка должна содержать корректные значения из всех трёх таблиц
  4. Тестовые данные:
    • orders с несуществующим user_id (при INNER JOIN не выведется)
    • NULL значения в полях (результат зависит от типа JOIN)
    • Дублирующиеся заказы одного пользователя на разные продукты

Выводы

  • INNER JOIN — это стандартный и безопасный выбор для этого случая
  • Порядок JOIN логичен: начинаем с центральной таблицы orders
  • Запрос оптимален и не требует дополнительных оптимизаций для таблиц среднего размера
  • Тестирование должно включать проверку целостности данных и граничных случаев
SQL запрос с JOIN | PrepBro