7.0 KiB
HAVING and Aggregate Functions
This document details the strategic application of the SQL HAVING clause and core aggregate functions. Mastery enables developers to write high-impact queries that efficiently process and filter grouped data, a critical requirement for performant applications.
Unlike the WHERE clause, which filters individual rows * before* grouping and aggregation, HAVING operates on grouped data after these operations have occurred. This distinction is fundamental for filtering based on aggregate results.
Syntax
The HAVING clause is applied after GROUP BY and before ORDER BY.
SELECT column_name(s)
FROM table_name
WHERE condition -- Filters individual rows (optional)
GROUP BY column_name(s) -- Groups rows with identical values
HAVING condition -- Filters groups based on aggregate results
ORDER BY column_name(s); -- Sorts the final result set (optional)
The HAVING condition typically involves one or more aggregate functions and comparison/logical operators.
Aggregate Functions
SQL aggregate functions transform a collection of values from multiple rows into a single summary value. They are indispensable for data analysis, reporting, and gaining insights from datasets. These functions operate on a set of values, not individual data points.
Core Aggregate Functions
| Function | Description | Application |
|---|---|---|
AVG() |
Calculates the average value of a numeric column. | Mean purchase amount, average salary. |
SUM() |
Calculates the total sum of a numeric column. | Total revenue, sum of expenses. |
COUNT() |
Counts the number of rows or non-null values. | Total transactions, user signups. |
MAX() |
Returns the largest value in a column. | Highest price, maximum score. |
MIN() |
Returns the smallest value in a column. | Lowest price, minimum score. |
Most aggregate functions disregard NULL values, with the exception of COUNT(*) which counts all rows regardless of NULL values.
Aggregate Function Examples
Consider the following tables:
Students
| rollno | name | class |
|---|---|---|
| 1 | Troy | TE |
| 1 | Shree | BE |
| 2 | Harry | TE |
| 3 | John | TE |
| 3 | Shiv ani | TE |
purchase
| item | price | customer_name |
|---|---|---|
| Pen | 10 | Troy |
| Bag | 1000 | Troy |
| Vegetables | 500 | Troy |
| Shoes | 5000 | Troy |
| Water Bottle | 800 | XYZ |
| Mouse | 120 | ABC |
| Sun Glasses | 1350 | ABC |
AVG function
Calculate the average purchase amount per customer.
SELECT AVG(price) AS Avg_Purchase, customer_name
FROM purchase
GROUP BY customer_name;
| Avg_Purchase | customer_name |
|---|---|
| 1 627.5000 | Troy |
| 800.0000 | XYZ |
| 735.0000 | ABC |
SUM function
Calculate the total expenditure for each customer.
SELECT SUM(price) AS Total_Bill, customer_name
FROM purchase
GROUP BY customer_name;
| Total_Bill | customer_name |
|---|---|
| 6510 | Troy |
| 800 | XYZ |
| 1470 | ABC |
COUNT function
Determine the number of items purchased by each customer.
SELECT COUNT(item) AS Total_Items, customer_name
FROM purchase
GROUP BY customer_name;
| Total_Items | customer _name |
|---|---|
| 4 | Troy |
| 1 | XYZ |
| 2 | ABC |
MAX function
Identify the highest single purchase value for each customer.
SELECT MAX(price) AS Highest_Purchase, customer_name
FROM purchase
GROUP BY customer_name;
| Highest_Purchase | customer_name |
|---|---|
| 5000 | Troy |
| 800 | XYZ |
| 1350 | ABC |
MIN function
Find the lowest single purchase value for each customer.
SELECT MIN(price) AS Lowest_Purchase, customer_name
FROM purchase
GROUP BY customer_name;
| Lowest_Purchase | customer_name |
|---|---|
| 10 | Troy |
| 800 | XYZ |
| 120 | ABC |
Having Clause Examples
These examples demonstrate using HAVING to filter results based on aggregate function output.
Example 1: Filtering by Group Count
Identify classes with more than 2 students.
SELECT COUNT(class) AS strength, class
FROM Students
GROUP BY class
HAVING COUNT(class) > 2;
This query provides the count of students per class, filtered to include only those classes where the count exceeds 2.
| strength | class |
|---|---|
| 4 | TE |
Example 2: Filtering by Minimum Aggregate Value
Find customers whose minimum purchase price is greater than 10.
SELECT customer_name, MIN(price) AS MIN_PURCHASE
FROM purchase
GROUP BY customer_name
HAVING MIN(price) > 10;
This query calculates the minimum purchase for each customer and includes only those customers where this minimum is above 10.
| customer_name | MIN_PURCHASE |
|---|---|
| XYZ | 800 |
| ABC | 120 |
Example 3: Filtering and Ordering by Average Aggregate Value
List customers with an average purchase price greater than 550, ordered by name descending.
SELECT customer_name, AVG(price) AS Average_Purchase
FROM purchase
GROUP BY customer_name
HAVING AVG(price) > 550
ORDER BY customer_name DESC;
This query computes the average purchase price per customer, filters for averages above 550, and presents the results in descending order of customer name.
| customer_name | Average_Purchase |
|---|---|
| XYZ | 800.0000 |
| Troy | 1627.5000 |
| ABC | 735.0000 |
Example 4: Combining WHERE and HAVING
Calculate the total purchase amount for customers whose names start with "S" and whose total purchase exceeds 1000.
SELECT customer_name, SUM(price) AS Total_Purchase
FROM purchase
WHERE customer_ name LIKE "S%" -- WHERE filters rows before grouping
GROUP BY customer_name
HAVING SUM(price) > 1000; -- HAVING filters groups after aggregation
This query first filters rows to include only customers whose names start with 'S', then groups by customer name, calculates the total purchase, and finally filters these groups to include only those with a total exceeding 1000. Combining WHERE and HAVING allows for efficient multi -stage filtering.
| customer_name | Total_Purchase |
|---|---|
| Troy | 6510 |