All posts
SQLSeptember 12, 20267 min read

SQL Aggregate Functions Explained (COUNT, SUM, AVG)

New to SQL? Learn aggregate functions COUNT, SUM, AVG, MIN, and MAX with simple, copy-pasteable examples every beginner can follow today.

F
Fepiq Team
Fepiq

SQL aggregate functions are built-in tools that take many rows of data and turn them into one summary number. The five you will use almost every day are COUNT(), SUM(), AVG(), MIN(), and MAX(). For example, COUNT() tells you how many rows match, and SUM() adds up a column of numbers. In this guide you will learn what each one does, with small, copy-pasteable examples you can run yourself.

What Is an Aggregate Function in SQL?

A table in a database is just rows and columns, like a spreadsheet. Normally, a SELECT query returns one row of output for every row that matches. An aggregate function is different: it looks at a whole column (or a whole group of rows) and returns a single value that summarizes them, such as a total, an average, or a count.

Think of a spreadsheet of orders. Instead of scrolling through 5,000 rows to find the total sales, you can ask the database to add them up for you in one line of SQL.

The 5 Most Common Aggregate Functions

FunctionWhat it doesExample
COUNT()Counts how many rows matchCOUNT(*) counts every row
SUM()Adds up all the values in a columnSUM(price) totals a price column
AVG()Calculates the average valueAVG(price) gives the mean price
MIN()Finds the smallest valueMIN(price) finds the cheapest item
MAX()Finds the largest valueMAX(price) finds the most expensive item

We will use one sample table called orders for every example below. It has three columns: id (a unique number for each order), customer (the customer's name), and amount (how much the order cost, in dollars).

COUNT() – Counting Rows

COUNT() answers the question "how many?". It is the aggregate function beginners reach for most often, because almost every report starts with a total number of something.

sql
SELECT COUNT(*) AS total_orders
FROM orders;

Line by line: SELECT COUNT(*) tells the database to count every row, no matter what is in it. AS total_orders just renames the result column so the output is easy to read (without it, the column would be called count, which is fine too). FROM orders says which table to look in. The result is a single row with one number, like 248.

You can also count a specific column instead of every row. COUNT(customer) counts only the rows where customer is not empty (in SQL, an empty or unknown value is called NULL). COUNT(*) counts all rows, including ones with NULL values; COUNT(column_name) skips NULLs in that column.

SUM() – Adding Up Numbers

SUM() adds every value in a numeric column together and returns one total. It only works on numbers, not on text.

sql
SELECT SUM(amount) AS total_revenue
FROM orders;

This adds up every value in the amount column across all rows in the orders table and labels the single result total_revenue. If your orders table has rows of 20, 35, and 45, this query returns 100. Rows where amount is NULL are treated as if they were not there, so they do not lower the total.

AVG() – Finding the Average

AVG() calculates the mean of a column: it adds up all the values, then divides by how many values there are (ignoring NULLs).

sql
SELECT AVG(amount) AS average_order_value
FROM orders;

AVG(amount) computes the average of every value in the amount column. For orders of 20, 35, and 45, AVG returns 33.33 (100 divided by 3). This is useful for questions like "what is our average order value?" without you having to calculate it by hand.

MIN() and MAX() – Smallest and Largest Values

MIN() returns the smallest value in a column, and MAX() returns the largest. They work on numbers, dates, and even text (alphabetically), which makes them useful far beyond just prices.

sql
SELECT MIN(amount) AS cheapest_order,
       MAX(amount) AS most_expensive_order
FROM orders;

This query runs two aggregate functions in the same SELECT statement, separated by a comma. MIN(amount) finds the lowest value in the amount column, and MAX(amount) finds the highest. The result is one row with two columns, showing both numbers side by side.

Combining Aggregate Functions with GROUP BY

So far every example summarized the entire table into one number. GROUP BY lets you get one summary number per group instead — for example, total spend per customer rather than one grand total for everyone.

sql
SELECT customer, SUM(amount) AS total_spent
FROM orders
GROUP BY customer;

GROUP BY customer tells the database to split the orders table into one group per unique customer name, before running SUM(amount) inside each group. The result is one row per customer, showing how much that customer spent in total. Any column you SELECT alongside an aggregate function (like customer here) must also appear in the GROUP BY clause.

Want a deeper look at how GROUP BY works, including grouping by multiple columns?

Read the SQL GROUP BY guide

Filtering Aggregated Results with HAVING

WHERE filters rows before they are grouped. But if you want to filter after the aggregate function has run — for example, only show customers who spent more than $100 in total — you need HAVING instead.

sql
SELECT customer, SUM(amount) AS total_spent
FROM orders
GROUP BY customer
HAVING SUM(amount) > 100;

This runs the same grouped SUM as before, but HAVING SUM(amount) > 100 removes any customer group whose total is 100 or less from the final result. You cannot write WHERE SUM(amount) > 100 here, because WHERE runs before grouping happens, and the total does not exist yet at that point.

Common Mistakes Beginners Make

  • Using WHERE to filter an aggregate result — use HAVING instead.
  • Forgetting to add non-aggregated columns to GROUP BY, which causes an error in most databases.
  • Assuming SUM() or AVG() include NULL values as zero — they simply skip them.
  • Mixing up COUNT(*) (all rows) with COUNT(column) (only non-NULL values in that column).
  • Trying to run an aggregate function on a text column with SUM() or AVG() — those two only work on numbers.

Frequently asked questions

What are aggregate functions in SQL?+

Aggregate functions are built-in SQL commands that take many rows of data and return a single summary value, such as a count, total, average, minimum, or maximum. The most common ones are COUNT(), SUM(), AVG(), MIN(), and MAX().

What is the difference between COUNT(*) and COUNT(column_name)?+

COUNT(*) counts every row in the result, no matter what values it contains. COUNT(column_name) counts only the rows where that specific column is not NULL (not empty). If a column has some missing values, the two counts can be different.

Do SUM() and AVG() count NULL values as zero?+

No. SUM() and AVG() both ignore NULL values completely rather than treating them as zero. AVG() also excludes NULL rows from the count it divides by, so the average only reflects rows that actually have a value.

Can I use more than one aggregate function in the same query?+

Yes. You can list several aggregate functions in one SELECT statement, separated by commas, such as SELECT COUNT(*), SUM(amount), AVG(amount) FROM orders. The database calculates all of them in a single pass over the table.

Why do I get an error when I add a normal column next to an aggregate function?+

Most databases require every non-aggregated column in your SELECT list to also appear in the GROUP BY clause. This is because the database needs to know how to group rows before it can decide what value to show for that column in each summary row.

Building an app or dashboard that needs solid database queries under the hood?

Talk to Fepiq about your project

Get new posts in your inbox

Occasional, no-fluff notes on shipping modern software — startups, automation, Laravel, Shopify and more. No spam, unsubscribe anytime.

Keep reading

Related posts

All posts

Let's build something

Ready to ship your next product with Fepiq?

Book a free discovery call. We'll listen, ask sharp questions, and send you a proposal within 3 business days.