SQL GROUP BY
Collapses many rows sharing the same value into one row per group — the foundation everything else in this series builds on.
What & Why
Every aggregate function covered so far (COUNT, SUM, AVG, MIN, MAX) collapsed an entire table down to a single summary row. That's useful, but real questions are usually more specific: not "what's the average page view count across all sessions," but "what's the average page view count per device." GROUP BY is what makes that possible.
Here's the core idea: GROUP BY column_name takes every row in the result and sorts it into a bucket based on that column's value. All rows sharing the same value land in the same bucket. Then, any aggregate function in the SELECT list is computed separately for each bucket — not once for the whole table, but once per group. The final result has exactly one row per distinct value in the grouped column, no matter how many original rows fed into it.
This is a genuinely different way of thinking about a query than anything covered in the Beginner track. Until now, every query returned one row per row in the source table (possibly filtered, sorted, or limited) — the row count in, roughly, is the row count out. GROUP BY breaks that assumption entirely: seven session rows can become three device rows. Getting comfortable with that mental shift is really the whole point of this lesson.
See How It Works
Growth wants the average number of page views per session for each device type.
| id | user_id | page_views | device |
|---|---|---|---|
| 5001 | 101 | 8 | desktop |
| 5002 | 102 | 3 | mobile |
| 5003 | 103 | 12 | desktop |
| 5004 | 104 | 1 | tablet |
| 5005 | 105 | 7 | mobile |
| 5006 | 106 | 5 | tablet |
| 5007 | 107 | 10 | desktop |
| session | device | page_views |
|---|---|---|
| 5001 | desktop | 8 |
| 5002 | mobile | 3 |
| 5003 | desktop | 12 |
| 5004 | tablet | 1 |
| 5005 | mobile | 7 |
| 5006 | tablet | 5 |
| 5007 | desktop | 10 |
Every session is still an individual source row.
SELECT
device,
ROUND(AVG(page_views), 2) AS avg_page_views
FROM growth.sessions
GROUP BY device
ORDER BY device;Practice this concept
Growth wants the average number of page views per session for each device type.
growthPrefix tables with growth.table_name.
deviceavg_page_viewsgrowth.sessions| Column | Type |
|---|---|
| id | bigint |
| user_id | integer |
| started_at | timestamp with time zone |
| ended_at | timestamp with time zone |
| page_views | integer |
| device | text |
| internal_session_score | integer |
Sign up free to try it on a real business scenario