SQL HAVING filters grouped rows after aggregation. Unlike WHERE, which filters individual rows before GROUP BY, HAVING applies conditions to aggregate results such as COUNT, SUM, AVG, MIN, and MAX. Use HAVING to keep only those groups that match specific aggregate criteria, combine it with GROUP BY, and avoid performance issues by limiting row volume early with WHERE.
SQL HAVING filters grouped rows after aggregation, keeping only groups that satisfy aggregate conditions like COUNT(>10) or SUM(<1000).
WHERE filters individual rows before grouping, so it cannot reference aggregates. HAVING evaluates after GROUP BY, allowing conditions on COUNT, SUM, AVG, MIN, or MAX.
SQL logically executes FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY. HAVING sees aggregate results that WHERE never sees, making it ideal for post-aggregation filtering.
Place HAVING after GROUP BY: SELECT col, COUNT(*) FROM table GROUP BY col HAVING COUNT(*) > 5;
. The clause can include multiple conditions joined by AND/OR.
Yes, but only if the column also appears in the GROUP BY list. Otherwise, the database cannot uniquely identify the value for each group and throws an error.
Use WHERE to cut down rows early for speed, then HAVING to filter the aggregated result. Example: first restrict a date range with WHERE, then apply HAVING COUNT(>100).
Yes. When no GROUP BY exists, the entire result set is treated as one group. HAVING can then filter on aggregates like SUM(sales) > 1000.
Chain conditions with AND or OR: HAVING SUM(sales) > 10000 AND AVG(discount) < 0.05
. Parentheses control precedence for complex logic.
Filter as much as possible in WHERE to reduce rows before GROUP BY, index columns used in WHERE and GROUP BY, and avoid putting non-aggregated columns in HAVING.
Window functions let you keep detailed rows while filtering on aggregates. Use COUNT(*) OVER (PARTITION BY col)
in a subquery, then apply WHERE to that derived table.
Always pair HAVING with GROUP BY unless filtering the entire set, combine WHERE and HAVING for speed, avoid SELECT *, and document why the aggregate thresholds were chosen.
Avoid HAVING when simple WHERE can do the job, such as filtering on non-aggregate columns. Using HAVING unnecessarily forces the database to aggregate before filtering.
HAVING filters groups after aggregation, complements WHERE, uses aggregate functions in conditions, and should be combined with indexing and early filtering for optimal performance.
Practice rewriting reports that currently use WHERE into GROUP BY/HAVING queries, explore window functions, and test performance differences in your database.
Use WHERE to filter individual rows before aggregation. Use HAVING to filter groups based on aggregate results like COUNT or SUM.
No. Aggregate functions are evaluated after WHERE. Place AVG() conditions in HAVING.
HAVING can be slower because it processes data after GROUP BY. Combine it with WHERE to reduce rows early.
Yes. Without GROUP BY, the entire result is one group, and HAVING filters that single aggregate row.