Lesson 6
Counting and adding up: aggregates
For readers who finished part 1 and can choose, filter and sort the rows of one table.
- Many rows into one
- COUNT
- SUM and AVG
- MIN and MAX
- Aggregates skip NULL
- Mixing in a plain column
- 5 exercises
Every query runs on real PostgreSQL, in your browser. It downloads once, about 6 MB, then starts in a few seconds.
For a reference page on the same statements, read SQL Aggregate Functions: COUNT, SUM, AVG, MIN, MAX, and GROUP BY.
The idea
An aggregate turns many rows into one value
An aggregate function reads a column over all the rows that WHERE keeps, and returns one value. The answer has a single row.
Try it
Several aggregates in one query
count(*) counts the rows, min and max find the smallest and largest value, and avg the average.
select count(*), min(price), max(price), avg(price) from products;
One row: 26 products, priced from 12.50 to 1899.00.
Try it
SUM adds up a column
select sum(quantity) from order_items where order_id = 7;
9 units in all, the 3 + 1 + 2 + 3 of the diagram.
Try it
ROUND keeps an average readable
An average rarely comes out even. round(value, 2) keeps two decimals.
select avg(price), round(avg(price), 2) from products;
287.6807692307692308 becomes 287.68.
Try it
MIN and MAX work on dates and text too
They work on any column that can be sorted: the earliest and latest date, or the first and last name in alphabetical order.
select min(order_date), max(order_date) from orders;
The orders run from 2025-01-01 to 2026-10-02.
Watch out
Every aggregate skips NULL, except count(*)
count(*) counts rows. count(phone) counts the values in phone, and a NULL is no value:
select count(*), count(phone)
from customers;
| count | count |
|---|---|
| 500 | 429 |
sum, avg, min and max ignore NULL too: an average, for one, is taken over the rows that have a value.
Watch out
A plain column cannot sit beside an aggregate
This asks for the name of the most expensive product:
select name, max(price)
from products;
ERROR: column "products.name" must appear in the GROUP BY clause or be used in an aggregate function
The aggregate makes one row out of 26, but there are 26 names, and PostgreSQL will not pick one. GROUP BY, in the message, is lesson 7. For the most expensive product, sort as in lesson 5: order by price desc limit 1.
Exercise 1 of 5
How many products are there? Answer with one number.
Expected result
It shows once PostgreSQL is ready.
Each check sends the exercise, your SQL and any PostgreSQL error to dbschema.com, without your IP address, so that the hints can improve.
Show answer
select count(*) from products
Exercise 2 of 5
Show the average product price, rounded to 2 decimals.
Expected result
It shows once PostgreSQL is ready.
Each check sends the exercise, your SQL and any PostgreSQL error to dbschema.com, without your IP address, so that the hints can improve.
Show answer
select round(avg(price), 2) from products
Exercise 3 of 5
Show the first and the last order date, in one row.
Expected result
It shows once PostgreSQL is ready.
Each check sends the exercise, your SQL and any PostgreSQL error to dbschema.com, without your IP address, so that the hints can improve.
Show answer
select min(order_date), max(order_date) from orders
Exercise 4 of 5
How many units were sold in all, over every order line?
Expected result
It shows once PostgreSQL is ready.
Each check sends the exercise, your SQL and any PostgreSQL error to dbschema.com, without your IP address, so that the hints can improve.
Show answer
select sum(quantity) from order_items
Exercise 5 of 5
In one query, show the number of customers and the number of customers who have a phone.
Expected result
It shows once PostgreSQL is ready.
Each check sends the exercise, your SQL and any PostgreSQL error to dbschema.com, without your IP address, so that the hints can improve.
Show answer
select count(*), count(phone) from customers