Docs
Docs/Aggregations & Grouping/HAVING Clause

HAVING Clause

Filter groups after aggregation

HAVING filters groups after aggregation. It's like WHERE, but for aggregate results.

WHERE vs HAVING

WHEREHAVING
Filters individual rowsFilters grouped results
Runs before GROUP BYRuns after GROUP BY
Can't use aggregatesCan use aggregates

Basic HAVING

-- Countries with more than 100 users
SELECT country, COUNT(*) AS user_count
FROM users
GROUP BY country
HAVING COUNT(*) > 100;

-- Customers who spent over $1000
SELECT user_id, SUM(total) AS total_spent
FROM orders
GROUP BY user_id
HAVING SUM(total) > 1000;

WHERE + HAVING Together

-- Active customers with 5+ orders in 2024
SELECT 
    user_id,
    COUNT(*) AS order_count,
    SUM(total) AS total_spent
FROM orders
WHERE status = 'completed'           -- Filter rows FIRST
  AND created_at >= '2024-01-01'
GROUP BY user_id
HAVING COUNT(*) >= 5                 -- Filter groups AFTER
ORDER BY total_spent DESC;

Execution Order

  1. 1. FROM / JOIN
  2. 2. WHERE (filter rows)
  3. 3. GROUP BY (create groups)
  4. 4. HAVING (filter groups)
  5. 5. SELECT (compute columns)
  6. 6. ORDER BY (sort results)
  7. 7. LIMIT (restrict output)

Need help?

Join our Discord community for support and discussions.

Join Discord