Keyboard Shortcuts N Next post
P Previous post
S Save / unsave
R Read aloud
T Toggle theme
/ Focus search
Esc Close panels
🔥
Ready to read...
aggregations Data Analytics Course intermediate Phase 4 — SQL SQL

SQL Aggregations — COUNT, SUM, AVG, MIN, MAX Explained

Reviewed & accurate
AI Summary

What You Will Learn

  • The five core SQL aggregation functions
  • How each one handles NULL values
  • Using DISTINCT inside aggregations
  • How aggregations combine with WHERE

Why This Topic Matters

Every report you will ever build is built on these five functions. Total revenue = SUM. Order count = COUNT. Average delivery time = AVG. Cheapest product = MIN. Most expensive = MAX. Master them now and the rest of SQL becomes much easier — especially GROUP BY in lesson 21, which is just aggregations applied per group.

The Five Functions

FunctionWhat it returnsExample
COUNTNumber of rowsCOUNT(*)
SUMTotal of numeric valuesSUM(amount)
AVGAverage (mean) of numeric valuesAVG(amount)
MINSmallest valueMIN(amount)
MAXLargest valueMAX(amount)

Sample Data

We extend our orders table with one more column, delivery_min, and one NULL row:

order_idcustomeramountdelivery_min
001Anita50032
002Ravi120047
003Mira750NULL
004Sam90028
005Anita150052

COUNT — How Many Rows?

SELECT COUNT(*) FROM orders;            → 5  (counts all rows)
SELECT COUNT(amount) FROM orders;       → 5  (counts non-NULL amount values)
SELECT COUNT(delivery_min) FROM orders; → 4  (skips the NULL!)
Important: COUNT(*) counts every row, including rows with NULLs. COUNT(column_name) counts only non-NULL values in that column. This difference bites beginners constantly.

COUNT(DISTINCT ...) — Unique Values

SELECT COUNT(DISTINCT customer) FROM orders;  → 4  (Anita, Ravi, Mira, Sam)
SELECT COUNT(DISTINCT city) FROM orders;      → 3  (Mumbai, Chennai, Kolkata)

Useful for "how many unique customers placed an order?"

SUM — Total of a Numeric Column

SELECT SUM(amount) FROM orders;       → 4850
SELECT SUM(delivery_min) FROM orders; → 159  (ignores the NULL row)

SUM automatically ignores NULLs — they do not contribute 0, they are skipped. If you SUM a column where every value is NULL, the result is NULL (not 0).

AVG — Average of Non-NULL Values

SELECT AVG(delivery_min) FROM orders;  → 39.75  (159 / 4, not 159 / 5)

This is a critical point: AVG ignores NULLs entirely. It does not treat them as 0. The denominator is the count of non-NULL values, not the count of all rows.

If you wanted "average delivery time including orders that have no recorded time as 0", you would write:

SELECT AVG(COALESCE(delivery_min, 0)) FROM orders;  → 31.8  (159 / 5)

COALESCE(delivery_min, 0) replaces NULL with 0 before averaging. Whether that is the right thing to do depends on the business question — usually it is not, because missing data is not the same as zero.

MIN and MAX — Smallest and Largest

SELECT MIN(amount) FROM orders;  → 500
SELECT MAX(amount) FROM orders;  → 1500
SELECT MIN(delivery_min) FROM orders;  → 28  (ignores NULL)
SELECT MAX(delivery_min) FROM orders;  → 52

MIN and MAX work on dates too:

SELECT MIN(ordered_at) AS first_order,
       MAX(ordered_at) AS latest_order
FROM orders;

Multiple Aggregations in One Query

You can compute several at once:

SELECT
  COUNT(*) AS order_count,
  SUM(amount) AS total_revenue,
  AVG(amount) AS avg_order_value,
  MIN(amount) AS smallest_order,
  MAX(amount) AS largest_order
FROM orders;

Result:

order_counttotal_revenueavg_order_valuesmallest_orderlargest_order
548509705001500

One query, five numbers. This is the foundation of every "summary" report.

Combining Aggregations with WHERE

WHERE filters before the aggregation runs. So this:

SELECT SUM(amount) AS mumbai_revenue
FROM orders
WHERE city = 'Mumbai';

First filters to Mumbai rows, then sums them. Result: 500 + 1500 = 2000.

The Aggregate Without GROUP BY Trap

When you use an aggregate function without GROUP BY, the entire result is one row — even if the query also selects a non-aggregated column. This:

SELECT customer, SUM(amount)
FROM orders;

Returns one row in strict SQL (most databases reject this; SQLite returns the first customer with the total sum — misleading). The fix is GROUP BY, which we cover in lesson 21.

NULL Handling Summary

FunctionBehavior on NULL
COUNT(*)Counts every row, NULL or not
COUNT(column)Skips NULL values in that column
SUMSkips NULL values; returns NULL if all values are NULL
AVGSkips NULL values; denominator = non-NULL count
MIN, MAXSkip NULL values

Common Mistakes

  1. Using COUNT(column) when you mean COUNT(*). If the column has NULLs, you undercount rows.
  2. Forgetting that AVG ignores NULLs. If 30% of delivery times are NULL, your "average" only reflects the 70% that were recorded — which may be a biased sample.
  3. Mixing aggregated and non-aggregated columns. SELECT customer, SUM(amount) FROM orders is invalid in most databases. Use GROUP BY.
  4. Summing a column stored as text. SUM silently returns 0 or an error. Convert types first.
  5. Confusing COUNT(DISTINCT col) with DISTINCT COUNT(*). The latter is not valid syntax. Use COUNT(DISTINCT col) to count unique values.

Practical Exercise (10 minutes)

Using the sample data above, write queries to compute:

  1. Total amount across all orders.
  2. Number of orders (use COUNT(*)).
  3. Average delivery time (ignoring NULLs).
  4. Smallest and largest amount.
  5. Number of unique customers.
  6. Total amount for Mumbai orders only.
  7. Average amount for orders placed by Anita.

Mini Challenge

Write a query that returns: total orders, total revenue, average revenue per order (computed two ways — once with AVG and once with SUM/COUNT), and the difference between them. The two averages should match if every row has an amount — but if NULLs exist, they will differ. Understanding why is the whole point of this lesson.

Key Takeaways

  • Five core aggregates: COUNT, SUM, AVG, MIN, MAX.
  • COUNT(*) counts rows; COUNT(column) counts non-NULL values.
  • AVG, SUM, MIN, MAX all silently skip NULLs.
  • Use COALESCE(col, 0) if you want NULLs treated as 0 (rarely the right call).
  • Combine with WHERE to filter before aggregating.
Course continuity
Previously learned: Lessons 17–19 covered SELECT, WHERE, ORDER BY, LIMIT.
Today: You learned the five aggregation functions and how they handle NULLs.
Next: Lesson 21 puts aggregations to work with GROUP BY — the SQL version of a pivot table.

FAQ

Why does SUM return NULL instead of 0 when all values are NULL?

Because SQL cannot know whether "no values" means "the total is zero" or "we have no data". If you want 0 instead, wrap with COALESCE: COALESCE(SUM(amount), 0).

Can I use COUNT(*) and SUM(amount) in the same query?

Yes. Mixing aggregates is fine: SELECT COUNT(*), SUM(amount), AVG(amount) FROM orders; returns one row with three values. The constraint is only that you cannot mix aggregates with non-aggregated columns without GROUP BY.

Test Your Knowledge
How did you find this?

Comments

Join the discussion! Sign in with your Google or Blogger account, or comment as Anonymous - no account needed. For quick questions, also reach me on Telegram @cytestch.

Comments