Atterna
RUEN
Get access

WHERE vs HAVING

WHERE filters rows before they are grouped; HAVING filters groups after aggregation, so it can use COUNT, SUM and other aggregates.

FormulaWHERE filters rows before GROUP BY · HAVING filters groups after

How we work it through

  1. 1

    Row conditions (status, date) go in WHERE.

  2. 2

    Conditions on aggregates (COUNT, SUM) go in HAVING.

  3. 3

    Read the query in execution order: FROM → WHERE → GROUP BY → HAVING → SELECT.

On the practice dataset

The query we run on Meridian, Atterna’s practice marketplace, and what it returns.

SELECT buyer_id, COUNT(*) AS paid_orders
FROM meridian.orders
WHERE status = 'paid'        -- rows
GROUP BY buyer_id
HAVING COUNT(*) >= 3;        -- groups

Result1,475 buyers with three or more paid orders

The common trap

Putting a row condition in HAVING (an error for a column that isn’t grouped, wasted work for one that is), or an aggregate in WHERE (always an error).

When an AI answers

An AI assistant

“SELECT buyer_id FROM orders GROUP BY buyer_id HAVING status = 'paid' AND COUNT(*) >= 3”

What it didn’t know
It put a row condition in HAVING; the database rejects it or it filters the wrong thing.
Ask back
“Move status = 'paid' to WHERE so it applies before grouping.”
Paste a real AI answer into the checker — it writes these questions for you →

Read next

Examples use Meridian, Atterna’s fictional practice marketplace.