Script Valley
SQL for Developers (Not DBAs)
Aggregations and GroupingLesson 2.1

COUNT, SUM, AVG, MIN, MAX — aggregate functions explained

aggregate functions, COUNT(*) vs COUNT(col), SUM, AVG, MIN, MAX, NULLs in aggregation, DISTINCT inside aggregates

Aggregates Collapse Many Rows Into One

Aggregate functions take a set of rows and return a single value. Without GROUP BY, they operate on every row in the table (or the rows surviving WHERE).

SELECT
  COUNT(*)            AS total_orders,
  COUNT(shipped_at)   AS shipped_orders,
  SUM(total_amount)   AS revenue,
  AVG(total_amount)   AS avg_order_value,
  MIN(total_amount)   AS smallest_order,
  MAX(total_amount)   AS largest_order
FROM orders
WHERE created_at >= '2024-01-01';

COUNT(*) vs COUNT(column)

COUNT(*) counts all rows, including those with NULLs. COUNT(column) counts only rows where that column is NOT NULL. This difference matters: if 200 orders exist but only 150 have a shipped_at date, COUNT(*) returns 200, COUNT(shipped_at) returns 150.

NULLs Are Silently Ignored

SUM, AVG, MIN, and MAX all skip NULL values automatically. If a discount column has NULLs mixed with numbers, AVG averages only the non-NULL rows — it does not treat NULL as zero. This is often not what you want:

-- Treat NULL discount as 0 for averaging
SELECT AVG(COALESCE(discount, 0)) AS avg_discount FROM orders;

DISTINCT Inside Aggregates

COUNT(DISTINCT column) counts unique non-NULL values:

-- How many unique customers placed orders?
SELECT COUNT(DISTINCT customer_id) FROM orders;

Up next

GROUP BY — aggregate data by category or value

Sign in to track progress

COUNT, SUM, AVG, MIN, MAX — aggregate functions explained — Aggregations and Grouping — SQL for Developers (Not DBAs) — Script Valley — Script Valley