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

Почему WHERE выполняется раньше JOIN?

1.3 Junior🔥 111 комментариев
#Основы Java

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

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

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

Порядок выполнения WHERE и JOIN в SQL

Вообще-то, это не совсем правильное утверждение в формулировке вопроса. WHERE не всегда выполняется раньше JOIN - порядок выполнения зависит от типа JOIN и контекста.

Логический порядок выполнения SQL запроса

Официальный порядок выполнения SQL (согласно стандарту ANSI SQL):

1. FROM       - определяем источники данных
2. JOIN       - объединяем таблицы
3. WHERE      - фильтруем объединённые строки
4. GROUP BY   - группируем результаты
5. HAVING     - фильтруем группы
6. SELECT     - выбираем столбцы
7. DISTINCT   - удаляем дубликаты
8. ORDER BY   - сортируем
9. LIMIT      - ограничиваем количество

Итак, JOIN выполняется раньше WHERE, но это касается фильтрации результатов объединения.

Различие между INNER JOIN и LEFT JOIN с фильтрацией

Это различие критично:

// Вариант 1: WHERE фильтрует ПОСЛЕ JOIN
SELECT * FROM users u
JOIN orders o ON u.id = o.user_id
WHERE o.status = "completed";

// Вариант 2: условие В JOIN фильтрует ДО объединения
SELECT * FROM users u
LEFT JOIN orders o ON u.id = o.user_id AND o.status = "completed"
WHERE u.active = true;

Вариант 1:

  • JOIN объединяет все заказы
  • WHERE фильтрует только завершённые

Вариант 2 с LEFT JOIN:

  • Условие в ON фильтрует заказы ДО присоединения
  • Пользователи остаются, даже если нет matching заказов
  • WHERE затем фильтрует пользователей

Практический пример с разными результатами

// Таблица users: id=1, id=2, id=3
// Таблица orders: (user_id=1, status="completed")
//                  (user_id=1, status="pending")
//                  (user_id=2, status="completed")

// Запрос с WHERE
SELECT u.id, o.id FROM users u
INNER JOIN orders o ON u.id = o.user_id
WHERE o.status = "completed";

// Результат: две строки (user 1 и 2 с completed заказами)

// Запрос с условием в JOIN
SELECT u.id, o.id FROM users u
LEFT JOIN orders o ON u.id = o.user_id AND o.status = "completed"
WHERE u.id > 0;

// Результат: три строки (все пользователи, но user 1 может появиться дважды)

Когда WHERE действительно важен

Для INNER JOIN разницы практически нет (WHERE и условие в ON дают одинаковый результат):

// Эти запросы эквивалентны
SELECT * FROM orders o
INNER JOIN customers c ON o.customer_id = c.id
WHERE c.country = "USA";

SELECT * FROM orders o
INNER JOIN customers c ON o.customer_id = c.id AND c.country = "USA";

Но для LEFT/RIGHT/FULL JOIN результаты могут отличаться:

// Все пользователи, даже без заказов, но только из США
SELECT * FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.country = "USA";

// Все пользователи (и не только из США), 
// но только заказы от США
SELECT * FROM users u
LEFT JOIN orders o ON u.id = o.user_id AND u.country = "USA";

Оптимизация запросов

Для лучшей производительности:

// Плохо - фильтруем ПОСЛЕ JOIN
SELECT * FROM users u
JOIN orders o ON u.id = o.user_id
WHERE u.status = "active"
AND o.total > 1000;

// Лучше - фильтруем РАНЬШЕ через подзапросы
SELECT * FROM (SELECT * FROM users WHERE status = "active") u
JOIN (SELECT * FROM orders WHERE total > 1000) o
ON u.id = o.user_id;

Оптимизатор базы данных может переставлять условия, но явное разделение логики помогает.

Вывод

WHERE выполняется ПОСЛЕ JOIN в логическом порядке, но для INNER JOIN это практически эквивалентно условию в ON. Для LEFT/RIGHT/FULL JOIN - важно понимать разницу, так как результаты будут отличаться.

Почему WHERE выполняется раньше JOIN? | PrepBro