Skip to content
Educora
Beginner14 min6 / 22

Aggregate functions: COUNT, SUM, AVG, MIN, MAX

Turn many rows into one number: count rows, add up values and find the average, the minimum and the maximum.

Check yourself
In this lesson you will learn
  • Use the five main aggregate functions
  • Explain the difference between COUNT(*), COUNT(column) and COUNT(DISTINCT column)
  • Combine aggregates with WHERE and know how NULL affects them

A teacher doesn't need every student's score — she needs the class average. A shop owner wants the total sales, not a look at every single order. The answer to such questions is not a list of rows but one number. In SQL these numbers are calculated by aggregate functions.

What is an aggregate function?

Definition
Aggregate function

A function that takes the values from many rows and calculates one result from them. A regular function (such as ROUND) works on each row separately; an aggregate works on all the rows at once.

FunctionWhat it returns
COUNT(*)the number of rows
COUNT(x)the number of non-NULL values of x
SUM(x)the sum of the values
AVG(x)the average
MIN(x)the smallest value
MAX(x)the largest value

COUNT: counting

COUNT has three forms. COUNT(*) counts all rows. COUNT(email) counts only the rows that have a value in email — two students have a NULL email, so the result is 10. COUNT(DISTINCT city) gives the number of different cities.

SQL
SELECT COUNT(*)             AS students,
       COUNT(email)         AS with_email,
       COUNT(DISTINCT city) AS cities
FROM students;
▸ Expected output
students | with_email | cities
12 | 10 | 7

SUM, AVG, MIN and MAX

You can put several aggregates in one query. An average is often a long decimal (here 293.558), so we round it with ROUND. The result is always a single row, because the whole table is summarised as one group.

SQL
SELECT SUM(stock)            AS total_items,
       ROUND(AVG(price), 2)  AS avg_price,
       MIN(price)            AS cheapest,
       MAX(price)            AS most_expensive
FROM products;
▸ Expected output
total_items | avg_price | cheapest | most_expensive
1086 | 293.56 | 3.2 | 1450

MIN and MAX work not only with numbers but also with text and dates. For dates in the YYYY-MM-DD format, MIN gives the earliest date and MAX the latest.

SQL
SELECT MIN(order_date) AS first_order,
       MAX(order_date) AS last_order
FROM orders;
▸ Expected output
first_order | last_order
2025-01-15 | 2025-07-07

Calculating with aggregates

The result of an aggregate is an ordinary number, so you can calculate with it. MAX(age) - MIN(age) gives the difference between the oldest and the youngest age. To find the percentage of students who have an email, divide COUNT(email) by COUNT(*) and multiply by 100. Careful: 100 * 10 / 12 is integer division and gives 83; for the exact result we write 100.0.

SQL
SELECT MAX(age) - MIN(age) AS age_range,
       100 * COUNT(email) / COUNT(*) AS int_pct,
       ROUND(100.0 * COUNT(email) / COUNT(*), 1) AS pct_with_email
FROM students;
▸ Expected output
age_range | int_pct | pct_with_email
3 | 83 | 83.3
int_pct lost its fraction because of integer division.

Aggregates and WHERE

WHERE works before the aggregate: first the rows are filtered, then the calculation runs only on the rows that are left. Below we take only the enrollments of course 1 (Algebra): 4 students, average score 87.3.

SQL
SELECT COUNT(*)             AS enrollments,
       ROUND(AVG(score), 1) AS avg_score,
       MIN(score)           AS min_score,
       MAX(score)           AS max_score
FROM enrollments
WHERE course_id = 1;
▸ Expected output
enrollments | avg_score | min_score | max_score
4 | 87.3 | 75 | 97
Worked example

What is the total value of all goods in the warehouse?

Show solution
The value of each product is price * stock.
An aggregate can contain an expression: SUM(price * stock).
The DBMS calculates the product for each row first and then adds them up: 40260.6.
SQL
SELECT SUM(price * stock) AS warehouse_value
FROM products;
▸ Expected output
warehouse_value
40260.6
SQL
SELECT AVG(age) AS avg_age
FROM students;
▸ Expected output
avg_age
15.5
Exercise

Summarise course number 1 (Algebra): the number of enrollments (students), the average score rounded to 1 decimal place (avg_score) and the highest score (best).

Exercise · SQL
SELECT COUNT(*) AS students
       -- add avg_score and best
FROM enrollments
WHERE course_id = 1;
▸ Expected output
students | avg_score | best
4 | 87.3 | 97
Exercise

For the Electronics category, find the number of products (products), the total number of items in stock (total_stock) and the lowest price (cheapest).

Exercise · SQL
SELECT
  -- three aggregates here
FROM products
WHERE category = 'Electronics';
▸ Expected output
products | total_stock | cheapest
4 | 63 | 120.5

Key points

  • An aggregate function calculates one result from many rows: COUNT, SUM, AVG, MIN, MAX.
  • COUNT(*) counts all rows, COUNT(x) the non-NULL ones and COUNT(DISTINCT x) the different values.
  • WHERE runs before the aggregate, so only the filtered rows are used.
  • Aggregates (except COUNT(*)) skip NULL values.
  • Don't mix an aggregate with a plain column without GROUP BY — most DBMSs treat it as an error.

Check yourself

10 questions. Every correct answer earns XP.

1 / 10
In students, COUNT(*) gives 12 but COUNT(email) gives 10. Why?