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

Что такое HAVING в SQL?

1.0 Junior🔥 171 комментариев
#Базы данных и SQL

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

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

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

Что такое HAVING в SQL

HAVING - это фильтр для агрегированных (GROUP BY) данных. Это WHERE, но для groups, а не для строк.

WHERE vs HAVING

WHERE:

  • Фильтрует строки ПЕРЕД группировкой
  • Работает с индивидуальными строками
  • Нельзя использовать агрегатные функции
  • Выполняется раньше

HAVING:

  • Фильтрует groups ПОСЛЕ группировки
  • Работает с результатами агрегации
  • Можно использовать агрегатные функции (SUM, COUNT, AVG)
  • Выполняется позже

ПРОСТОЙ ПРИМЕР

Таблица с заказами: order_id | customer_id | amount 1 | 101 | 100 2 | 101 | 50 3 | 102 | 200 4 | 102 | 75 5 | 103 | 150

Задача 1: Найти заказы, где amount больше 100 (WHERE)

SELECT * FROM orders WHERE amount > 100;

Результат: order_id 3 (200), order_id 5 (150)

Задача 2: Найти customers, у которых СРЕДНИЙ заказ больше 100 (HAVING)

SELECT customer_id, AVG(amount) FROM orders GROUP BY customer_id HAVING AVG(amount) > 100;

Результат: customer_id 102: avg 137.5 customer_id 103: avg 150

ПОРЯДОК ВЫПОЛНЕНИЯ SQL

  1. FROM - выбираем таблицу
  2. WHERE - фильтруем строки
  3. GROUP BY - группируем
  4. HAVING - фильтруем группы
  5. SELECT - выбираем столбцы
  6. ORDER BY - сортируем

ПРАКТИЧЕСКИЕ ПРИМЕРЫ

Пример 1: Departments, где average salary более 50000

SELECT department, AVG(salary) FROM employees GROUP BY department HAVING AVG(salary) > 50000;

Пример 2: Products, которые проданы более 100 раз

SELECT product_id, COUNT() as sales FROM sales GROUP BY product_id HAVING COUNT() > 100 ORDER BY sales DESC;

Пример 3: Customers, потратившие более 1000 в 2024

SELECT customer_id, SUM(amount) FROM orders WHERE YEAR(order_date) = 2024 GROUP BY customer_id HAVING SUM(amount) > 1000;

Пример 4: Города с более 5 customers

SELECT city, COUNT(customer_id) FROM customers GROUP BY city HAVING COUNT(customer_id) > 5;

КОГДА ИСПОЛЬЗОВАТЬ HAVING

✓ Нужно фильтровать на основе агрегированных данных ✓ Используешь GROUP BY ✓ Нужно фильтровать группы, а не строки

Условия для HAVING:

  • HAVING COUNT(*) больше 10 - группы с более 10 строк
  • HAVING SUM(amount) меньше 1000 - сумма меньше 1000
  • HAVING AVG(price) больше или равно 100 - average цена
  • HAVING MAX(salary) больше 150000 - максимум salary
  • HAVING COUNT(user_id) больше 5 - более 5 пользователей

COMMON ОШИБКИ

Ошибка 1: Использование WHERE с агрегатной функцией

НЕПРАВИЛЬНО: SELECT department, AVG(salary) FROM employees WHERE AVG(salary) > 50000 GROUP BY department;

ПРАВИЛЬНО: SELECT department, AVG(salary) FROM employees GROUP BY department HAVING AVG(salary) > 50000;

Ошибка 2: Забыли GROUP BY

НЕПРАВИЛЬНО: SELECT customer_id, SUM(amount) FROM orders HAVING SUM(amount) > 500;

ПРАВИЛЬНО: SELECT customer_id, SUM(amount) FROM orders GROUP BY customer_id HAVING SUM(amount) > 500;

WHERE И HAVING ВМЕСТЕ

Основное использование - WHERE и HAVING вместе:

SELECT category, AVG(price), COUNT() FROM products WHERE active = true GROUP BY category HAVING COUNT() > 5 AND AVG(price) > 100;

Здесь:

  • WHERE отсеивает неактивные продукты
  • GROUP BY группирует по категориям
  • HAVING отсеивает категории с менее 5 продуктов

ПРОИЗВОДИТЕЛЬНОСТЬ

Быстрее: SELECT department, COUNT() FROM employees WHERE salary > 50000 GROUP BY department HAVING COUNT() > 5;

Медленнее: SELECT department, COUNT() FROM employees GROUP BY department HAVING salary > 50000 AND COUNT() > 5;

Почему? WHERE отсеивает строки ДО группировки (меньше данных для обработки).

ПРАКТИЧЕСКИЙ СОВЕТ

Когда пишешь query с GROUP BY:

  1. Фильтрую на основе агрегата (SUM, COUNT, AVG)?

    • ДА → HAVING
    • НЕТ → WHERE
  2. Фильтрую на основе отдельных строк?

    • ДА → WHERE
    • НЕТ → HAVING

ИТОГ

HAVING - это фильтр для групп. Это очень полезно для анализа данных. WHERE фильтрует строки, HAVING фильтрует группы. Порядок: WHERE выполняется перед GROUP BY, HAVING - после.