PostgreSQL HAVING Clause
The HAVING clause in PostgreSQL is used to filter aggregated results based on a condition. It is typically used with GROUP BY to filter the grouped rows after aggregation. While the WHERE clause filters rows before aggregation, the HAVING clause filters after aggregation.
1. Syntax of HAVING
aggregate_function(column3): The aggregation function, likeCOUNT(),SUM(),AVG(),MAX(), orMIN(), applied tocolumn3.HAVING: This filters the groups created byGROUP BYbased on the result of the aggregate function.
2. Example: Using HAVING with GROUP BY
Example 1: Get Departments with More Than 5 Employees
Consider the following tables:
employees: Contains employee details (e.g.,employee_id,department_id,salary).departments: Contains department details (e.g.,department_id,department_name).
Query: Retrieve Departments Having More Than 5 Employees
- This query returns departments that have more than 5 employees. The
HAVINGclause filters the result ofCOUNT()after grouping the employees bydepartment_id.
3. Example: Using HAVING with Other Aggregate Functions
Example 2: Get Products with a Total Sales Greater than 1000
Consider the sales table with the columns: product_id, quantity, and price.
Query: Retrieve Products with Total Sales Greater Than 1000
- This query calculates the total sales for each product and returns products with sales greater than 1000. The
HAVINGclause filters the total sales after the aggregation.
4. Example: HAVING with DISTINCT
You can use HAVING to filter unique aggregated results.
Example 3: Get Customers Who Have Made More Than 3 Purchases
Consider the orders table with customer_id and order_id.
Query: Retrieve Customers Who Have Placed More Than 3 Orders
- This query retrieves customers who have made more than 3 unique orders, filtering based on the count of distinct
order_ids.
5. Combining HAVING with WHERE
WHEREfilters rows before aggregation, whileHAVINGfilters after aggregation.- You can use both
WHEREandHAVINGin the same query.WHEREfilters rows before the grouping, andHAVINGfilters groups after aggregation.
Example 4: Filter Orders from the Year 2025 with Total Sales Greater than 1000
Consider the orders table with order_date, quantity, and price.
Query: Retrieve Orders from 2025 with Total Sales Greater Than 1000
- In this query,
WHEREfilters the rows from the year 2025, andHAVINGfilters the total sales result after aggregation.
6. Performance Considerations
- Efficiency:
HAVINGcan slow down queries because it filters data after aggregation. For large datasets, ensure that indexes are used on columns involved in filtering and grouping to optimize performance. HAVINGvs.WHERE: Always prefer usingWHEREfor filtering rows before aggregation. UseHAVINGwhen you need to filter based on aggregated data.
7. Summary of HAVING
| Operation | SQL Command |
|---|---|
| Filter Groups After Aggregation | SELECT ... FROM ... GROUP BY ... HAVING ... |
| Filter Rows Before Aggregation | Use WHERE before the GROUP BY clause. |
| Usage | Use HAVING to filter results based on aggregated data like COUNT(), SUM(), AVG(), etc. |
Would you like to see more complex examples or have questions about filtering data? 🚀

