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

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

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

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

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

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

Разница между HAVING и WHERE в SQL (поправка к вопросу)

Предположу, что вопрос имеет в виду разницу между HAVING и WHERE в SQL, а не VALUES, так как HAVING и WHERE — это два разных инструмента для фильтрации данных в SQL. Если же имелся в виду VALUES, то это синтаксис для вставки/конструирования данных, что совсем другое.

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

WHERE и HAVING — это две разные конструкции для фильтрации данных, но они работают на разных этапах обработки запроса:

-- WHERE фильтрует ДО группировки
SELECT department, COUNT(*) as employee_count
FROM employees
WHERE salary > 50000  -- этот фильтр применяется ДО GROUP BY
GROUP BY department
HAVING COUNT(*) > 5;  -- этот фильтр применяется ПОСЛЕ GROUP BY

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

WHERE работает с отдельными строками и применяется ДО агрегирования. Используется для:

  • Исключения строк из выборки на ранней стадии
  • Фильтрации по значениям столбцов
  • Уменьшения объема данных для обработки
-- Пример: найти всех сотрудников с зарплатой > 50000 по отделам
SELECT department, COUNT(*) as count
FROM employees
WHERE salary > 50000  -- фильтруем строки ДО группировки
GROUP BY department;

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

-- ОШИБКА! Это не работает
SELECT department, COUNT(*) as count
FROM employees
WHERE COUNT(*) > 5  -- ❌ нельзя использовать агрегирующие функции
GROUP BY department;

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

HAVING работает с группами и применяется ПОСЛЕ агрегирования. Используется для:

  • Фильтрации групп по результатам агрегирующих функций
  • Проверки условий, которые зависят от COUNT, SUM, AVG и т.д.
  • Исключения групп, не соответствующих условиям
-- Правильно! Найти отделы, где более 5 сотрудников
SELECT department, COUNT(*) as count
FROM employees
GROUP BY department
HAVING COUNT(*) > 5;  -- ✅ фильтруем группы ПОСЛЕ GROUP BY

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

Важно понимать, в каком порядке выполняется SQL запрос:

1. FROM       — источник данных
2. WHERE      — фильтрация строк ДО группировки
3. GROUP BY   — агрегирование
4. HAVING     — фильтрация групп ПОСЛЕ агрегирования
5. SELECT     — выбор столбцов
6. ORDER BY   — сортировка
LIMIT         — ограничение количества результатов

Практический пример с полной цепочкой:

SELECT 
    department, 
    AVG(salary) as avg_salary,
    COUNT(*) as employee_count
FROM employees
WHERE hire_date > '2020-01-01'         -- шаг 2: исключаем старых сотрудников
GROUP BY department                     -- шаг 3: группируем по отделу
HAVING AVG(salary) > 60000              -- шаг 4: только отделы с высокой средней зарплатой
ORDER BY avg_salary DESC                -- шаг 6: сортируем
LIMIT 10;                               -- шаг 7: показываем только 10

Примеры для понимания

Пример 1: WHERE исключает строки

-- Все сотрудники (от 1 до 10)
SELECT COUNT(*) FROM employees;
-- Результат: 10

-- Только те, чья зарплата > 50000 (может быть 7 человек)
SELECT COUNT(*) FROM employees WHERE salary > 50000;
-- Результат: 7

Пример 2: HAVING фильтрует группы

-- Все отделы
SELECT department FROM employees GROUP BY department;
-- Результат: Sales, IT, HR, Marketing (4 отдела)

-- Только отделы с более чем 5 сотрудниками
SELECT department FROM employees 
GROUP BY department 
HAVING COUNT(*) > 5;
-- Результат: Sales, IT (2 отдела)

Пример 3: Комбинирование WHERE и HAVING

SELECT 
    department,
    COUNT(*) as employee_count,
    AVG(salary) as average_salary
FROM employees
WHERE salary > 30000                    -- исключаем низкооплачиваемых
GROUP BY department
HAVING COUNT(*) > 3                     -- только отделы с 3+ сотрудниками
ORDER BY average_salary DESC;

Когда использовать

ЗадачаИспользуй
Фильтр по значению столбцаWHERE
Фильтр по количеству строк в группеHAVING
Фильтр по сумме/средней в группеHAVING
Исключение строк на ранней стадии (оптимизация)WHERE
Проверка условия для группыHAVING

Оптимизация производительности

WHERE лучше, чем HAVING для фильтрации строк, потому что:

-- ❌ Менее эффективно: группируем, потом фильтруем группы
SELECT department, COUNT(*) 
FROM employees
GROUP BY department
HAVING salary > 50000;  -- это работает, но может быть медленнее

-- ✅ Более эффективно: фильтруем строки, потом группируем
SELECT department, COUNT(*)
FROM employees
WHERE salary > 50000
GROUP BY department;

Попытка использовать WHERE для фильтрации по агрегирующей функции невозможна синтаксически, но если это можно перенести в WHERE — это всегда предпочтительнее для производительности.

Итоговая таблица

ХарактеристикаWHEREHAVING
Когда применяетсяДО GROUP BYПОСЛЕ GROUP BY
Работает сОтдельными строкамиГруппами строк
Агрегирующие функцииНельзяМожно и нужно
Примеры функцийСравнение столбцовCOUNT, SUM, AVG, MAX, MIN
ОптимизацияУменьшает объем данныхУменьшает количество групп
В чём разница между HAVING и VALUES? | PrepBro