Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Aggregate Queries  ›  Lesson

GROUP BY — One Answer per Group

GROUP BY 15 minGROUP BY splits rows into groups sharing the same values and runs aggregates once per group, so every selected column must be grouped or aggregated.

GROUP BY — One Answer per Group

"Total items sold" is one number. "Total items sold per customer" is a small table: one line for each customer. That little word per is the signal for GROUP BY, which runs an aggregate separately for each group of rows instead of once for the whole table.

The rule

Every selected column is either in GROUP BY or inside an aggregate.

order_id customer_id product_id quantity status
101 1 1 2 shipped
102 2 3 1 pending
103 1 2 5 shipped
104 3 1 1 cancelled
105 3 2 3 shipped
SELECT customer_id, SUM(quantity) AS items
FROM orders
GROUP BY customer_id;
customer_id items
1 7
2 1
3 4

GROUP BY sorts the rows into piles — one pile per distinct customer_id — and SUM runs once per pile. Customer 1's pile holds orders 101 and 103, so 2 + 5 = 7.

Now the rule. customer_id is in GROUP BY, so each pile has exactly one value of it and it can be shown. SUM(quantity) is an aggregate, so it produces one value per pile. But status is neither: customer 1's pile has only "shipped", but customer 3's has "cancelled" and "shipped", so there is no single answer. Adding status to that SELECT list is rejected by PostgreSQL, SQL Server and modern MySQL.

You can group by several columns (GROUP BY customer_id, status makes a pile for each combination), and WHERE still runs first, removing rows before they are grouped. Rows with NULL in the grouping column form one group of their own. The order of the output groups is not guaranteed, so add ORDER BY when it matters.

The shortcut

Find the word "per" (or "for each", "by") in the question. Whatever follows it goes in GROUP BY and in SELECT. Everything else in SELECT must be an aggregate.

Number of orders per statusStep 1 of 4
  1. Find "per"

    "Orders per status" — status is the group.

Drills

Answer fast — trust the rule.

quick drill

In SELECT customer_id, SUM(quantity) FROM orders GROUP BY customer_id;, what is customer 3's total?

quick drill

Why is SELECT customer_id, status, SUM(quantity) FROM orders GROUP BY customer_id; rejected by most databases?

quick drill

How many rows does SELECT status, COUNT(*) FROM orders GROUP BY status; return?

quick drill

Which query gives the number of customers per city?

Remember

  • Every selected column is either in GROUP BY or inside an aggregate.
  • Find "per": that column goes in GROUP BY and in SELECT.
  • WHERE removes rows before grouping; add ORDER BY if the order of groups matters.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainWhy the grouping rule exists

Explain in your own words why SQL requires every selected column to be either in GROUP BY or inside an aggregate. Use the orders table grouped by customer_id and the status column as your example.