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

В чём разница между WHERE и HAVING в SQL?

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

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

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

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

В чём разница между WHERE и HAVING в SQL?

WHERE и HAVING — это две разные клаузулы фильтрации в SQL, которые работают на разных этапах обработки запроса и имеют разные области применения. Это один из самых важных вопросов для Data Analyst, так как неправильное их использование приводит к ошибкам в аналитике.

Основные различия:

ХарактеристикаWHEREHAVING
Когда применяетсяДо группировки (GROUP BY)После группировки (GROUP BY)
На что действуетНа строки исходной таблицыНа результаты агрегирующих функций
Использование с функциямиНельзя использовать агрегирующие функцииМожно использовать агрегирующие функции
ПроизводительностьБолее эффективна (фильтрует данные до группировки)Менее эффективна (фильтрует после агрегации)

WHERE — фильтрация строк ДО группировки:

WHERE применяется к отдельным строкам таблицы, прежде чем они будут сгруппированы. Здесь нельзя использовать агрегирующие функции (COUNT, SUM, AVG и т.д.).

-- Пример: отобрать только заказы со статусом completed, затем сгруппировать
SELECT 
    customer_id,
    COUNT(*) as order_count,
    SUM(amount) as total_amount
FROM orders
WHERE status = completed  -- Фильтруем до группировки
GROUP BY customer_id;

Здесь WHERE фильтрует строки таблицы orders, оставляя только завершённые заказы, а затем выполняется группировка.

HAVING — фильтрация групп ПОСЛЕ группировки:

HAVING применяется после выполнения GROUP BY и агрегирующих функций. Здесь можно и нужно использовать функции COUNT, SUM, AVG и другие.

-- Пример: группируем по покупателям и отобираем только тех, у кого более 5 заказов
SELECT 
    customer_id,
    COUNT(*) as order_count,
    SUM(amount) as total_amount
FROM orders
GROUP BY customer_id
HAVING COUNT(*) > 5;  -- Фильтруем результаты группировки

Здесь HAVING фильтрует группы, оставляя только те, где количество заказов больше 5.

Практический пример с обеими клаузулами:

-- Найти категории товаров с общей стоимостью продаж > 10000
-- ВСЕ условия: статус заказа = completed, сумма по группе > 10000

SELECT 
    p.category,
    COUNT(o.id) as order_count,
    SUM(o.amount) as total_sales,
    AVG(o.amount) as avg_order_value
FROM orders o
JOIN products p ON o.product_id = p.id
WHERE o.status = completed           -- Условие на уровне строк
  AND o.order_date >= 2024-01-01     -- Условие на уровне строк
GROUP BY p.category
HAVING SUM(o.amount) > 10000            -- Условие на уровне групп
  AND COUNT(o.id) >= 10;                -- Условие на уровне групп

Почему это важно для производительности:

Правильный порядок фильтрации:

  1. WHERE фильтрует как можно больше строк ДО группировки (экономит вычисления)
  2. Затем выполняется GROUP BY с агрегирующими функциями
  3. HAVING фильтрует финальные результаты
-- Хорошо: WHERE сначала отфильтрует большой объём данных
SELECT department, COUNT(*) as emp_count
FROM employees
WHERE salary > 50000
GROUP BY department
HAVING COUNT(*) > 5;

Типичные ошибки:

Неправильно — использовать агрегирующую функцию в WHERE:

SELECT customer_id, SUM(amount)
FROM orders
WHERE SUM(amount) > 1000  -- ОШИБКА!
GROUP BY customer_id;

Правильно — использовать HAVING для фильтрации по агрегату:

SELECT customer_id, SUM(amount)
FROM orders
GROUP BY customer_id
HAVING SUM(amount) > 1000;

Понимание разницы между WHERE и HAVING критично для написания эффективных аналитических запросов и оптимизации производительности базы данных.

В чём разница между WHERE и HAVING в SQL? | PrepBro