Как в SQL можно выполнить фильтрацию по результату агрегатной функции без использования HAVING?

«Как в SQL можно выполнить фильтрацию по результату агрегатной функции без использования HAVING?» — вопрос из категории Базы данных, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Клаузу HAVING используют для фильтрации результатов группировки (GROUP BY). Без неё ту же логику можно реализовать с помощью подзапроса в FROM или WITH (CTE), где фильтрация выполняется в основном запросе через WHERE.

Пример: Найти пользователей с более чем 5 заказами.

С HAVING:

SELECT user_id, COUNT(*) as order_count
FROM orders
GROUP BY user_id
HAVING COUNT(*) > 5;

Без HAVING, с использованием подзапроса:

SELECT user_id, order_count
FROM (
    SELECT user_id, COUNT(*) as order_count
    FROM orders
    GROUP BY user_id
) AS user_order_stats
WHERE order_count > 5;

Или с использованием CTE (Common Table Expression):

WITH user_order_stats AS (
    SELECT user_id, COUNT(*) as order_count
    FROM orders
    GROUP BY user_id
)
SELECT user_id, order_count
FROM user_order_stats
WHERE order_count > 5;

Когда это полезно:

  • Когда условие фильтрации сложное и его удобнее вынести.
  • В некоторых случаях планировщик запросов СУБД может оптимизировать подзапрос эффективнее.
  • Для улучшения читаемости, если нужно выполнить несколько операций с агрегированными данными.

Недостаток: Запрос становится более многословным. Для простых условий HAVING — это стандартный и часто наиболее оптимальный выбор.