SQL Aggregate Functions – MIN, MAX, COUNT, SUM, AVG with Examples (2026)
SQL aggregate functions perform calculations on a set of values and return a single summary result. Instead of looking at every row individually, aggregate functions let you answer questions like — "What is the highest salary?", "How many employees are there?", "What is the total payroll cost?", or "What is the average salary per department?" The five essential SQL aggregate functions are MIN(), MAX(), COUNT(), SUM(), and AVG(). In this beginner-friendly guide you will learn each function with clear syntax and real working examples — including how to use them with GROUP BY and HAVING for powerful per-group reporting.
✅ What are SQL Aggregate Functions?
✅ Aggregate functions compute a single result from multiple rows — they summarise your data.
✅ They are used in the SELECT clause and work on a set of rows (the whole table or per group with GROUP BY).
✅ Most aggregate functions automatically ignore NULL values (except COUNT(*)).
SUM(Salary). Number of active employees? COUNT(*). Highest bonus? MAX(Bonus). Average age? AVG(Age). These functions are essential for any SQL-based reporting.
✅ Sample Employees Table used in all examples:-
| ID | Name | Department | Salary | Bonus |
|---|---|---|---|---|
| 1 | ANNI | IT | 10000 | 1000 |
| 2 | POOJA | IT | 90000 | 5000 |
| 3 | RAJ | HR | 5000 | NULL |
| 4 | SUJAN | HR | 8000 | 2000 |
| 5 | MEENA | Sales | 12000 | 3000 |
✅ The 5 Main Aggregate Functions at a Glance
✅ MIN() – Find the Lowest Value
MIN() returns the smallest value in a column — works with numbers, text (alphabetical), and dates.
✅ SELECT Query:-
SELECT MIN(Salary) AS MinSalary FROM Employees;
✅ Result:-
| MinSalary |
|---|
| 5000 |
SELECT MIN(Name) FROM Employees; returns 'ANNI' — alphabetically the first name. MIN() works on any comparable data type.
✅ MAX() – Find the Highest Value
MAX() returns the largest value in a column.
✅ SELECT Query:-
SELECT MAX(Salary) AS MaxSalary FROM Employees;
✅ Result:-
| MaxSalary |
|---|
| 90000 |
✅ COUNT() – Count the Number of Rows
COUNT() returns the number of rows. COUNT(*) counts all rows including NULLs; COUNT(column) counts only non-NULL values.
✅ SELECT Query:-
-- Count all rows:
SELECT COUNT(*) AS TotalEmployees FROM Employees;
-- Count only non-NULL bonus values:
SELECT COUNT(Bonus) AS EmployeesWithBonus FROM Employees;
✅ Result:-
| Query | Result |
|---|---|
| COUNT(*) | 5 |
| COUNT(Bonus) | 4 |
✅ SUM() – Calculate the Total
SUM() returns the total sum of all non-NULL values in a numeric column.
✅ SELECT Query:-
SELECT SUM(Salary) AS TotalPayroll FROM Employees;
✅ Result:-
| TotalPayroll |
|---|
| 125000 |
✅ AVG() – Calculate the Average
AVG() returns the average (mean) of all non-NULL values in a numeric column.
✅ SELECT Query:-
SELECT AVG(Salary) AS AvgSalary FROM Employees;
✅ Result:-
| AvgSalary |
|---|
| 25000 |
AVG(Bonus) divides by 4, not 5, because RAJ's bonus is NULL.
✅ All 5 Functions in One Query
You can use multiple aggregate functions in a single SELECT statement.
✅ SELECT Query:-
SELECT
MIN(Salary) AS MinSalary,
MAX(Salary) AS MaxSalary,
COUNT(*) AS TotalEmployees,
SUM(Salary) AS TotalPayroll,
AVG(Salary) AS AvgSalary
FROM Employees;
✅ Result:-
| MinSalary | MaxSalary | TotalEmployees | TotalPayroll | AvgSalary |
|---|---|---|---|---|
| 5000 | 90000 | 5 | 125000 | 25000 |
✅ Aggregate Functions with GROUP BY
Combine aggregate functions with GROUP BY to calculate statistics per group — such as total salary per department.
✅ SELECT Query:-
SELECT Department,
COUNT(*) AS Employees,
MIN(Salary) AS MinSalary,
MAX(Salary) AS MaxSalary,
SUM(Salary) AS TotalSalary,
AVG(Salary) AS AvgSalary
FROM Employees
GROUP BY Department;
✅ Result:-
| Department | Employees | MinSalary | MaxSalary | TotalSalary | AvgSalary |
|---|---|---|---|---|---|
| HR | 2 | 5000 | 8000 | 13000 | 6500 |
| IT | 2 | 10000 | 90000 | 100000 | 50000 |
| Sales | 1 | 12000 | 12000 | 12000 | 12000 |
✅ How Aggregate Functions Handle NULL
| Function | Handles NULL? | Behaviour with NULL |
|---|---|---|
COUNT(*) | ✅ Includes NULLs | Counts ALL rows including NULL rows |
COUNT(column) | ❌ Skips NULLs | Counts only non-NULL values in that column |
SUM(column) | ❌ Skips NULLs | Adds only non-NULL values; NULL treated as absent |
AVG(column) | ❌ Skips NULLs | Divides by count of non-NULL values only |
MIN(column) | ❌ Skips NULLs | Returns lowest non-NULL value |
MAX(column) | ❌ Skips NULLs | Returns highest non-NULL value |
AVG(Bonus) on our table = (1000+5000+2000+3000) ÷ 4 = 2750. It divides by 4 (non-NULL count), NOT 5 (total rows). This means AVG can be misleadingly high if many rows have NULL. Use COALESCE(Bonus, 0) to treat NULLs as zero when needed.
✅ WHERE vs HAVING with Aggregate Functions
Both filter rows, but they operate at different stages of the query:
| Clause | When it filters | Can use aggregate functions? | Example |
|---|---|---|---|
| WHERE | Before aggregation (on individual rows) | ❌ No | WHERE Salary > 5000 |
| HAVING | After aggregation (on group results) | ✅ Yes | HAVING AVG(Salary) > 10000 |
✅ Example — Departments where total salary exceeds 50000:-
SELECT Department, SUM(Salary) AS TotalSalary
FROM Employees
GROUP BY Department
HAVING SUM(Salary) > 50000;
✅ Result:-
| Department | TotalSalary |
|---|---|
| IT | 100000 |
✅ Key Points to Remember
✅ MIN() — smallest value; works on numbers, text, and dates.
✅ MAX() — largest value; works on numbers, text, and dates.
✅ COUNT(*) — counts ALL rows including NULLs.
✅ COUNT(column) — counts only non-NULL values in that column.
✅ SUM() — total of non-NULL numeric values only.
✅ AVG() — average of non-NULL values; divides by non-NULL count.
✅ Always alias results — AS MinSalary makes output column names readable.
✅ GROUP BY — calculates aggregates per group/category.
✅ HAVING — filters groups after aggregation (use HAVING for aggregate conditions, WHERE for row conditions).
✅ Clause order — SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT.
✅ Common SQL Aggregate Function Mistakes to Avoid
Wrong:
WHERE AVG(Salary) > 50000 — syntax error; aggregate functions cannot be used in WHERE.Correct:
HAVING AVG(Salary) > 50000 after GROUP BY.
Wrong:
SELECT Department, COUNT(*) FROM Employees; — most databases require non-aggregated columns to appear in GROUP BY.Correct:
SELECT Department, COUNT(*) FROM Employees GROUP BY Department;
COUNT(*) counts all rows (includes NULLs). COUNT(column) counts only non-NULL values. For data quality checks, always use COUNT(column) to know how many rows actually have a value.
Wrong:
SELECT SUM(Name) FROM Employees; — causes a data type error.SUM() and AVG() only work on numeric columns (INT, DECIMAL, FLOAT). Always ensure the column contains numbers before aggregating.
✅ Frequently Asked Questions (FAQ)
SELECT Department, SUM(Salary) FROM Employees GROUP BY Department; returns the total salary for each department separately.HAVING AVG(Salary) > 50000.SELECT MIN(Salary), MAX(Salary), AVG(Salary), SUM(Salary), COUNT(*) FROM Employees; returns all five statistics in a single row output.