13. Filtering Groups with HAVING

Core Idea: HAVING filters grouped rows after aggregation occurs. In contrast, WHERE filters individual base table records before any grouping is performed.

Syntax Shape

SELECT Category, COUNT(*) FROM Products GROUP BY Category HAVING COUNT(*) > 5;

Multiple Conditions in HAVING

SELECT DepartmentID, AVG(Salary) AS AvgSal, COUNT(*) AS HeadCount FROM Employees WHERE Status = 'Active' GROUP BY DepartmentID HAVING AVG(Salary) > 65000 AND COUNT(*) >= 3;

Practical Scenarios

Identifying high-volume product categories, locating departments exceeding headcount thresholds, or detecting repeating duplicate email entries.

Advanced Deep Dive ADVANCED

HAVING vs WHERE Execution Order: WHERE filters row-by-row before aggregations are computed. HAVING evaluates against the synthesized summary rows.

Performance Best Practice: Filter non-aggregated criteria in WHERE to minimize row volume before the costly grouping and aggregation steps.

Aggregate Functions: HAVING conditions can reference any aggregate function (COUNT, SUM, MAX, MIN, AVG), even ones not present in the SELECT list.

Null Grouping Logic: Summary groups consisting of NULL values will be included unless filtered explicitly with HAVING Category IS NOT NULL.

next