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

BUSINESS QUESTION

Growth wants the average number of page views per session for each device type.

iduser_idpage_viewsdevice
50011018desktop
50021023mobile
500310312desktop
50041041tablet
50051057mobile
50061065tablet
500710710desktop
Watch rows sort into groups, then collapseStep 1 of 4
-- 7 individual session rows, no grouping applied yet
sessiondevicepage_views
5001desktop8
5002mobile3
5003desktop12
5004tablet1
5005mobile7
5006tablet5
5007desktop10

Every session is still an individual source row.

EXAMPLE QUERY
SELECT
  device,
  ROUND(AVG(page_views), 2) AS avg_page_views
FROM growth.sessions
GROUP BY device
ORDER BY device;
Now You Try

Practice this concept

Growth wants the average number of page views per session for each device type.

Available schema
growth

Prefix tables with growth.table_name.

deviceavg_page_views
growth.sessions
ColumnType
idbigint
user_idinteger
started_attimestamp with time zone
ended_attimestamp with time zone
page_viewsinteger
devicetext
internal_session_scoreinteger
query.sql
Intermediate business practice

Sign up free to try it on a real business scenario