GROUP BY
max(sal) gives the highest salary in the school. The more useful question is the highest salary in each city — one answer per city, from one query. That is what group by is for.
1Sort the rows into piles
Picture the twelve teachers as cards on a desk. Deal them into piles, one pile per city. Now run max(sal) separately on each pile. You get one answer per pile, not one answer overall.
Rows are grouped by the value in the named column.
The function runs once inside each group.
The resultset has one row per group, not per teacher.
Run the three steps below before reading on — the middle one is the part a finished resultset never shows you.
Twelve teachers go in. Five rows come out — one per city, not one per teacher.
Twelve separate rows. Nothing has been grouped yet — this is what where would filter.
2The highest salary in each city
Twelve teachers became five rows — one per city. Each number is the top salary within that city, and 62000 is the largest of them, which matches the plain max(sal) from two lessons ago. Grouping did not change the data; it changed how it was divided up before the function ran.
3Counting within each group
count(*) with group by is the commonest combination of the two, and answers “how many in each…?”:
Two plus three plus three plus two plus two is twelve, so every teacher is in exactly one pile. That sum is a quick way to check a grouped result.
group by makes the piles but does not arrange them. Add order by grade on the end when the order matters — and it usually does in a report.4NULL gets a pile of its own
One teacher has no designation recorded. Group by that column and the missing values are gathered together, just as distinct gathered them:
Four groups: three real designations and one for “not recorded”. This is the same behaviour as distinct and the opposite of the aggregates, which skip NULLs. Grouping is about the column you group by; skipping is about the column you aggregate.
5The rule that catches everyone
Every plain column in the select must also appear in the group by.
In every example above, the only non-aggregate column selected — city, grade, designation — is the one being grouped by. That is not a coincidence.
Ask for select name, max(sal) from teachers group by city; and the query is asking for a single name from a pile of three teachers. There is no sensible answer, so it is not a sensible question.
6Where the clause goes
select <columns and aggregates> from <table> where <condition on rows> group by <column> order by <column>;
The order is fixed, and it is also the order things happen in: where throws rows away first, then the survivors are grouped, then the result is sorted. Because where runs before the grouping, it can only test individual rows — never a group total. Filtering the groups themselves is the next lesson.
7Recap
Splits rows into piles by that column's value.
Not one per record. The aggregate runs inside each pile.
Unlike the aggregates, which skip NULLs.
Every plain column selected must be in the group by.
12 teachers live in 5 different cities. How many rows does select count(*), city from teachers group by city; return?
Why is select name, max(sal) from teachers group by city; a bad query?
One teacher has NULL in designation. What does group by designation do with that row?