SQL Tutorial

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(*)).

💡 Real-world use: Every business report uses aggregate functions. Monthly payroll total? 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:-

Employees
IDNameDepartmentSalaryBonus
1ANNIIT100001000
2POOJAIT900005000
3RAJHR5000NULL
4SUJANHR80002000
5MEENASales120003000

✅ The 5 Main Aggregate Functions at a Glance

MIN()
Returns the smallest value in a column
MAX()
Returns the largest value in a column
COUNT()
Returns the number of rows or non-NULL values
SUM()
Returns the total sum of a numeric column
AVG()
Returns the average value of a numeric column

✅ 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:-

Result
MinSalary
5000
💡 MIN() with text: 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:-

Result
MaxSalary
90000
ℹ️ Use case: MAX() is used to find the highest score, the most recent date, the most expensive product, or the largest order amount — any time you need the top value from a column.

✅ 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:-

Result
QueryResult
COUNT(*)5
COUNT(Bonus)4
⚠️ Key difference: COUNT(*) = 5 (all rows). COUNT(Bonus) = 4 — RAJ has NULL bonus so it is not counted. Always use COUNT(column) when you need to know how many rows actually have a value.

✅ 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:-

Result
TotalPayroll
125000
💡 Calculation: 10000 + 90000 + 5000 + 8000 + 12000 = 125000. SUM() only works on numeric columns — using it on text columns causes an error.

✅ 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:-

Result
AvgSalary
25000
ℹ️ Calculation: (10000 + 90000 + 5000 + 8000 + 12000) ÷ 5 = 25000. AVG() automatically excludes NULLs from both the sum and the count — so 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:-

Result — All 5 Aggregate Functions
MinSalaryMaxSalaryTotalEmployeesTotalPayrollAvgSalary
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:-

Result — Statistics Per Department
DepartmentEmployeesMinSalaryMaxSalaryTotalSalaryAvgSalary
HR250008000130006500
IT2100009000010000050000
Sales112000120001200012000
💡 This is the most powerful SQL reporting pattern. GROUP BY + aggregate functions let you build payroll summaries, sales reports, inventory counts, and any per-category statistics with just one query.

✅ How Aggregate Functions Handle NULL

FunctionHandles NULL?Behaviour with NULL
COUNT(*)✅ Includes NULLsCounts ALL rows including NULL rows
COUNT(column)❌ Skips NULLsCounts only non-NULL values in that column
SUM(column)❌ Skips NULLsAdds only non-NULL values; NULL treated as absent
AVG(column)❌ Skips NULLsDivides by count of non-NULL values only
MIN(column)❌ Skips NULLsReturns lowest non-NULL value
MAX(column)❌ Skips NULLsReturns highest non-NULL value
⚠️ AVG() and NULL trap: 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:

ClauseWhen it filtersCan use aggregate functions?Example
WHEREBefore aggregation (on individual rows)❌ NoWHERE Salary > 5000
HAVINGAfter aggregation (on group results)✅ YesHAVING 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:-

Result
DepartmentTotalSalary
IT100000
ℹ️ Only IT qualifies: HR total = 13000, Sales total = 12000 — both under 50000. IT total = 100000 — exceeds 50000, so only IT appears. This is the HAVING clause in action.

✅ 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 resultsAS 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

❌ Mistake 1: Using aggregate functions in WHERE
Wrong: WHERE AVG(Salary) > 50000 — syntax error; aggregate functions cannot be used in WHERE.
Correct: HAVING AVG(Salary) > 50000 after GROUP BY.
❌ Mistake 2: Mixing aggregated and non-aggregated columns without 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;
❌ Mistake 3: Confusing COUNT(*) and COUNT(column)
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.
❌ Mistake 4: Using SUM() or AVG() on text columns
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)

What are SQL aggregate functions?
SQL aggregate functions perform a calculation on a set of values and return a single summary value. The five main functions are: MIN() (lowest value), MAX() (highest value), COUNT() (number of rows), SUM() (total of values), and AVG() (average of values).
What is the difference between COUNT(*) and COUNT(column)?
COUNT(*) counts ALL rows including those with NULL values. COUNT(column_name) counts only rows where that specific column is NOT NULL. If a column has 2 NULL values in 5 rows, COUNT(*) returns 5 but COUNT(column) returns 3.
How do aggregate functions handle NULL values?
Most aggregate functions (MIN, MAX, SUM, AVG, COUNT with column name) automatically skip NULL values. Only COUNT(*) includes NULLs. For AVG, NULLs are excluded from both the sum and the count — so AVG of (10, 20, NULL) is 15, not 10.
Can I use aggregate functions with GROUP BY?
Yes — GROUP BY is how you calculate aggregates per category. Example: SELECT Department, SUM(Salary) FROM Employees GROUP BY Department; returns the total salary for each department separately.
What is the difference between WHERE and HAVING with aggregate functions?
WHERE filters individual rows BEFORE aggregation. HAVING filters groups AFTER aggregation. You cannot use aggregate functions in a WHERE clause — use HAVING for that: HAVING AVG(Salary) > 50000.
Can I use multiple aggregate functions in one query?
Yes. You can use as many as needed in one SELECT: SELECT MIN(Salary), MAX(Salary), AVG(Salary), SUM(Salary), COUNT(*) FROM Employees; returns all five statistics in a single row output.

✍️ About the Author: Pramod Behera

Pramod Behera is a SAP and SQL educator with 10+ years of experience in enterprise software and database systems. He founded LearnToSAP.com to help beginners learn SAP and SQL concepts through clear, practical, real-world examples. His tutorials have helped thousands of students and IT professionals across India and beyond.