GROUP BY

RoadmapsSQL

Overview

GROUP BY collapses rows that share the same value(s) in the grouping column(s) into a single summary row. Before GROUP BY you have many individual rows; after it, you have one row per unique group. Crucially, WHERE filters individual rows BEFORE GROUP BY collapses them. Any column in SELECT must either appear in the GROUP BY list or be wrapped in an aggregate function (COUNT, SUM, etc.). Against the shared dataset: SELECT status, COUNT(*) AS order_count FROM orders GROUP BY status ORDER BY status; The 8 order rows collapse into 3 groups: cancelled (1), paid (6), pending (1). Think of GROUP BY as putting rows into labelled buckets — one bucket per unique grouping-key value — and then squeezing each bucket down to a single summary row.

Almost every reporting or analytics query needs GROUP BY. Without it, you can only look at individual rows. GROUP BY lets you answer 'how many?', 'what total?', and 'what average?' for each category — the bread and butter of dashboards and business metrics.

Where used: analytics dashboards, summary statistics APIs, report generation

Why learn this

Query walkthrough

SELECT status, COUNT(*) AS order_count
FROM orders
GROUP BY status
ORDER BY status;

Focus: Watch 8 individual order rows collapse into 3 group rows — one per distinct status value.

Common mistakes

Glossary

collapse
To shrink or merge multiple related rows into a single summary row.
prerequisite
A foundational concept or skill that you must understand first before you can learn something more advanced.
aggregate
A function that takes multiple rows of data and performs a calculation to return a single summarized value.

Recall questions

Understanding checks

What rows does this return?

US | 3 AE | 1 JP | 1 MX | 1 UK | 1

WHERE removes Emma (NULL country) first, leaving 7 rows. GROUP BY collapses those 7 rows into 5 groups by country. US has 3 customers (Alice, Bob, Greg); the other 4 countries have 1 each. ORDER BY n DESC puts US first, then the tie-breaking alphabetical order.

What rows does this return?

cancelled | 1 paid | 6 pending | 1

The 8 orders have statuses: paid (orders 1,2,4,6,7,8 = 6), pending (order 3 = 1), cancelled (order 5 = 1). GROUP BY collapses each status into one row, ORDER BY status sorts alphabetically.

Practice tasks

Group by category instead of status

This query counts orders by status. Modify it to count products by category from the products table instead, keeping an ORDER BY on category.

Challenge

Orders per customer

Write a query that shows each customer's name and how many orders they placed. Only include customers who have at least one order. Order by name.

Continue learning

Previous: SELECT, FROM & Columns

Previous: WHERE & Operators

Next: Aggregate Functions

Next: Multi-Column Grouping

Next: OVER & PARTITION BY

Return to SQL Roadmap