Lesson 4  ·  Oct 7, 2026
Data Engineering Fundamentals

One summary per group with GROUP BY

Aggregates collapse a whole table into one number. GROUP BY goes one step further: it splits rows into buckets first, then computes one aggregate per bucket. One number per country, per day, per category — the breakdown behind every dashboard chart.

The code

Station counts per country, for stations west of 100°W:

SELECT country, COUNT(*) AS num_stations
FROM weather_stations
WHERE lon < -100.0
GROUP BY country;

The execution order matters:

  1. WHERE lon < -100.0 — filter rows first.
  2. GROUP BY country — bucket the survivors by country.
  3. COUNT(*) — tally each bucket. One result row per country.

Every column in the SELECT must either be in the GROUP BY or wrapped in an aggregate — otherwise the database can't know which row's value you mean.

In practice

This is the single most useful query shape in analytics: revenue per month, errors per service, users per plan. If you've ever written .groupby() in pandas after pulling a whole table, this is the same operation — pushed into the database where it belongs.

Python bridge: df[df.lon < -100].groupby('country').size(). Filter, group, summarize — identical verbs, identical order, in both languages.

Try it

Practice question: using this sample of weather_stations, predict the result of the query above. Then add AVG(elevation) AS avg_elevation to the SELECT — how does the result change?

countrylonelevation
USA-110.21500
USA-105.5800
Canada-120.0600
Mexico-99.5200
USA-115.02100
Show answer
SELECT country, COUNT(*) AS num_stations
FROM weather_stations
WHERE lon < -100.0
GROUP BY country;

Two rows: USA → 3 stations, Canada → 1. Mexico never makes it to grouping — its lon of -99.5 fails the WHERE filter, so it's gone before any bucket exists.

SELECT country, COUNT(*) AS num_stations,
       AVG(elevation) AS avg_elevation
FROM weather_stations
WHERE lon < -100.0
GROUP BY country;
countrynum_stationsavg_elevation
USA31466.7
Canada1600.0

Same two rows, one extra column — the shape doesn't change, the summary per group just gets richer. USA's average elevation is (1500 + 800 + 2100) / 3 = 1466.7; Canada's is 600.

Further reading

GROUP BY in SQL: How to Aggregate and Analyze Data Efficiently

← All posts