1 Aggregate Functions
TopAggregate functions take a column of values and return a single value — a count, a total, an average. You already saw them briefly with GROUP BY; now let's master each one.
COUNT — How Many?
-- How many sales did we make?
SELECT COUNT(*) AS total_sales FROM sales;total_sales ----------- 7
-- How many sales per salesperson?
SELECT salesperson,
COUNT(*) AS deals
FROM sales
GROUP BY salesperson
ORDER BY deals DESC;salesperson | deals ---------------|------ Sara Ahmed | 2 James Wilson | 2 Priya Sharma | 2 David Chen | 1
COUNT(*) vs COUNT(column): COUNT(*) counts all rows, including those with NULL values. COUNT(column) counts only rows where that column is not NULL. If you want to know how many rows have a phone number: COUNT(phone).
SUM — What's the Total?
-- Total revenue (amount x quantity for each sale)
SELECT SUM(amount * quantity) AS total_revenue
FROM sales;total_revenue ------------- 2186.60
-- Revenue breakdown by region
SELECT region,
SUM(amount * quantity) AS revenue,
SUM(quantity) AS units_sold
FROM sales
GROUP BY region
ORDER BY revenue DESC;region | revenue | units_sold ------------|----------|---------- Asia | 1197.72 | 30 Europe | 489.83 | 17 Middle East | 498.97 | 4
AVG — What's the Average?
-- Average sale amount
SELECT ROUND(AVG(amount), 2) AS avg_amount
FROM sales;avg_amount ---------- 83.99
-- Average sale per salesperson
SELECT salesperson,
ROUND(AVG(amount * quantity), 2) AS avg_deal_value
FROM sales
GROUP BY salesperson
ORDER BY avg_deal_value DESC;salesperson | avg_deal_value ---------------|--------------- Priya Sharma | 598.86 Sara Ahmed | 174.49 James Wilson | 244.92 David Chen | 399.80
MAX and MIN — Extremes
-- Biggest and smallest single sale
SELECT
MAX(amount) AS highest_price,
MIN(amount) AS lowest_price,
MAX(quantity) AS biggest_order,
MAX(sale_date) AS most_recent
FROM sales;highest_price | lowest_price | biggest_order | most_recent --------------|--------------|---------------|---------- 199.00 | 19.99 | 20 | 2025-03-28
Combining Everything: A Sales Dashboard Query
-- Complete sales dashboard by salesperson
SELECT
salesperson,
COUNT(*) AS deals,
SUM(quantity) AS units,
SUM(amount * quantity) AS revenue,
ROUND(AVG(amount), 2) AS avg_price,
MAX(sale_date) AS last_sale
FROM sales
GROUP BY salesperson
HAVING SUM(amount * quantity) > 300
ORDER BY revenue DESC;salesperson | deals | units | revenue | avg_price | last_sale ---------------|-------|-------|----------|-----------|---------- Priya Sharma | 2 | 10 | 797.92 | 124.50 | 2025-03-14 James Wilson | 2 | 17 | 489.83 | 34.99 | 2025-02-18 Sara Ahmed | 2 | 4 | 348.97 | 124.50 | 2025-01-22 David Chen | 1 | 20 | 399.80 | 19.99 | 2025-03-28
Remember: Aggregate functions ignore NULL values. AVG(salary) with values 100, NULL, 200 returns 150 (not 100). If NULLs should count as zero, use AVG(COALESCE(salary, 0)).
Key Takeaways
-
COUNT(*)= number of rows;COUNT(col)= non-NULL values only -
SUM(col)= total;AVG(col)= average;MAX/MIN= extremes - Pair with
GROUP BYfor per-category/per-person breakdowns - Use
HAVINGto filter groups after aggregation - All aggregate functions skip NULL values — use COALESCE if you need NULLs counted as zero