top of page

SQL HAVING Clause with Examples

In T-SQL, you should use the HAVING clause when you want to filter the results of a query based on aggregated values, especially when working with grouped data using the GROUP BY clause. Here are some scenarios when you should use HAVING in T-SQL:


Filtering Grouped Data: Use HAVING to filter groups of rows based on aggregate conditions. For example, when you want to retrieve groups that meet specific criteria, such as total sales exceeding a certain threshold or the count of items in a group being greater than a certain value.

SELECT category, SUM(revenue) AS total_revenue
FROM sales
GROUP BY category
HAVING SUM(revenue) > 1000; 

Applying Aggregate Conditions: When you need to filter groups based on aggregate functions like SUM, AVG, COUNT, etc., HAVING is the appropriate clause to use. This allows you to apply conditions to the aggregated results.

SELECT category, AVG(revenue) AS average_revenue
FROM sales
GROUP BY category
HAVING AVG(revenue) > 200; 

Combining Filters: You can use HAVING to combine multiple aggregate conditions within the same query. This is useful when you need to filter groups based on multiple criteria simultaneously.

SELECT category, SUM(revenue) AS total_revenue, COUNT(product_id) AS product_count
FROM sales
GROUP BY category
HAVING SUM(revenue) > 1000 AND COUNT(product_id) > 10; 

Filtering After Grouping: Unlike the WHERE clause, which filters rows before they are grouped, HAVING filters groups after they have been aggregated. This allows you to filter based on summarized data, rather than individual rows.

SELECT order_date, SUM(total_amount) AS daily_revenue
FROM orders
WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BY order_date
HAVING SUM(total_amount) > 10000; 

In summary, you should use the HAVING clause in T-SQL when you need to filter aggregated results based on specific conditions. It provides a way to apply conditions to grouped data, allowing for more nuanced analysis and reporting.

SQL Having Syntax

The syntax for the HAVING clause in SQL is as follows:

SELECT column1, column2, aggregate_function(column3)
FROM table_name
GROUP BY column1, column2
HAVING condition; 

Here’s a breakdown of the syntax:


SELECT: Specifies the columns to be retrieved in the result set.


column1, column2, …: The columns to be selected.


aggregate_function(column3): The aggregate function applied to column3 or any other column in the SELECT list. Common aggregate functions include SUM, AVG, COUNT, MIN, and MAX.


FROM: Specifies the table from which to retrieve the data.


table_name: The name of the table or tables from which to retrieve data.


GROUP BY: Groups the rows based on the specified columns.


column1, column2, …: The columns used for grouping.


HAVING: Filters the grouped results based on specified conditions.


condition: The condition that each group must satisfy. It can include comparisons, arithmetic operations, or other logical conditions.

Here’s an example using the HAVING clause:

SELECT category, SUM(revenue) AS total_revenue
FROM sales
GROUP BY category
HAVING SUM(revenue) > 1000; 

In this example, the HAVING clause filters the groups based on the total revenue of condition group being greater than 1000. Only groups meeting this condition will be included in the result set.

Having Examples

Here’s an overview of the SQL HAVING clause with examples:

SELECT column1, column2, aggregate_function(column3)
FROM table_name
GROUP BY column1, column2
HAVING condition; 

Example 1: Simple Aggregate Filtering

Suppose we have a table named Sales with columns Product, Category, and Revenue. We want to find categories with total revenue greater than $1000.

SELECT Category, SUM(Revenue) AS TotalRevenue
FROM Sales
GROUP BY Category
HAVING SUM(Revenue) > 1000; 

Example 2: Aggregate Filtering with WHERE Clause

We can combine the WHERE clause to filter rows before grouping and the HAVING clause to filter groups after grouping. For example, we want to find categories with total revenue greater than $1000 and where the total number of products sold is greater than 10.

SELECT Category, SUM(Revenue) AS TotalRevenue, COUNT(Product) AS ProductCount
FROM Sales
WHERE SaleDate BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BY Category
HAVING SUM(Revenue) > 1000 AND COUNT(Product) > 10; 

Example 3: Filtering with Aggregate Functions

We can also use aggregate functions directly in the HAVING clause. For instance, we want to find categories with an average revenue per product greater than $200.

SELECT Category, AVG(Revenue) AS AvgRevenuePerProduct
FROM Sales
GROUP BY Category
HAVING AVG(Revenue) > 200; 

Example 4: Using Aliases in HAVING Clause

We can use column aliases defined in the SELECT clause within the HAVING clause following query above. For instance, we want to find categories with total revenue greater than the average revenue of all categories.

SELECT Category, SUM(Revenue) AS TotalRevenue
FROM Sales
GROUP BY Category
HAVING SUM(Revenue) > (SELECT AVG(TotalRevenue) FROM (SELECT SUM(Revenue) AS TotalRevenue FROM Sales GROUP BY Category) AS CategoryRevenue); 

In summary, the HAVING clause is used with the GROUP BY clause to filter grouped rows based on specified conditions. It is particularly useful for filtering aggregated results.

HAVING vs GroupBy

The GROUP BY and HAVING clauses in SQL serve different purposes, but they are often used together for more sophisticated data analysis. Here’s an explanation of each with examples:

GROUP BY Clause:

The GROUP BY clause is used to group rows that have the same values into summary rows. It is typically used in conjunction with aggregate functions to perform calculations on grouped data.

Example: Suppose we have a table named sales with columns category and revenue. We want to calculate the total revenue for each category.

SELECT category, SUM(revenue) AS total_revenue
FROM sales
GROUP BY category; 

In this example, the GROUP BY clause groups the rows by the category column, and the SUM aggregate function calculates the total revenue for each category.

HAVING Clause:

The HAVING clause is used to filter the results of a GROUP BY clause based on specified conditions. It allows you to apply certain conditions to aggregated data.

Example: Building upon the previous example, suppose we want to find categories with total revenue exceeding $1000.

SELECT category, SUM(revenue) AS total_revenue
FROM sales
GROUP BY category
HAVING SUM(revenue) > 1000; 

In this example, the HAVING clause filters the groups based on value on the condition that the sum of revenue (SUM(revenue)) for each category must be greater than $1000.

Difference:


GROUP BY: Groups rows based on the values of one or more columns.


HAVING: Filters the grouped results based on specified conditions.

In summary, the GROUP BY clause is used in database, to group rows with the same values, while the HAVING clause is used to filter the grouped results based on specified conditions. Both clauses are powerful tools for analyzing and summarizing data in SQL queries.

SQL Having vs WHERE

The HAVING and WHERE clauses in SQL are both used to filter data, but they operate at different stages of the query execution and have different purposes. Here’s a comparison of the two:

WHERE Clause:


The WHERE clause is used to filter rows from the result set before any grouping or aggregation takes place.


It operates on individual rows in the original table(s) and is applied before the GROUP BY clause (if present) in a query.


Conditions specified in the WHERE clause filter individual rows based on column values.


Typically used with non-aggregated data.


Cannot be used with aggregated values.

Example:

SELECT column1, column2
FROM table_name
WHERE condition; 

HAVING Clause:


The HAVING clause is used to filter grouped rows based on aggregate conditions after the GROUP BY clause has been applied.


It operates on grouped rows and is applied after the GROUP BY clause (if present) in a query.


Conditions specified in the HAVING clause filter groups of rows based on aggregated values.


Typically used with aggregated data.


Can only be used with aggregated values.

Example:

SELECT column1, SUM(column2) AS total
FROM table_name
GROUP BY column1
HAVING SUM(column2) > 100; 

Differences:


Scope: WHERE clause filters individual rows, while HAVING clause filters grouped rows.


Aggregation: WHERE clause cannot be used with aggregated values, while HAVING clause can only be used with aggregated values.


Timing: WHERE clause is applied before grouping, while HAVING clause is applied after grouping.

In summary, use the WHERE clause to filter individual rows based specified condition or on column values, and use the HAVING clause to filter groups of rows based on aggregate conditions. Choosing the appropriate clause depends on the specific requirements of your query and whether you are working with aggregated or non-aggregated data.

The HAVING clause is often used with aggregate functions like COUNT() to filter groups of rows based on specified conditions. Here are some examples of using the HAVING clause with the COUNT() function:

Example 1: Filtering Groups with COUNT() Greater Than a Threshold

Suppose we have a table named orders with columns customer_id and order_id. We want to find customers who have placed more than 3 orders.

SELECT customer_id, COUNT(order_id) AS order_count
FROM orders
GROUP BY customer_id
HAVING COUNT(order_id) > 3; 

In this example, the HAVING clause filters the customers group the groups based on the condition that the count of orders (COUNT(order_id)) for each customer must be greater than 3.

Example 2: Filtering Groups with COUNT() Less Than or Equal to a Threshold

Suppose we want to find customers who have placed 3 or fewer orders.

SELECT customer_id, COUNT(order_id) AS order_count
FROM orders
GROUP BY customer_id
HAVING COUNT(order_id) <= 3; 

Here, the HAVING clause filters the groups based on the condition that the count of orders (COUNT(order_id)) for each customer must be less than or equal to 3.

Example 3: Filtering Groups with Non-Zero COUNT()

Suppose we want to find customers who have placed at least one order.

SELECT customer_id, COUNT(order_id) AS order_count
FROM orders
GROUP BY customer_id
HAVING COUNT(order_id) > 0; 

In this example, the HAVING clause filters the groups based on the condition that the count of orders (COUNT(order_id)) for each customer must be greater than 0, indicating that the customer has placed at least one order.

Example 4: Filtering Groups with NULL COUNT()

Suppose we want to find customers who have not placed any orders.

SELECT customer_id, COUNT(order_id) AS order_count
FROM orders
GROUP BY customer_id
HAVING COUNT(order_id) IS NULL; 

Additional Resources

SQL Having

Get in Touch

Thanks for submitting!

bottom of page