MAX, MIN, SUM & AVG
Every query so far has answered “which rows?”. These answer a different kind of question: the highest salary, the total paid out, the class average. Many rows go in and one value comes out.
1Many rows in, one value out
The examples here use the teachers table — twelve teachers, with a sal column. Note that one of them, Nirmala Devi, has NULL for salary; that becomes important very quickly.
The largest value
The smallest value
Everything added up
The mean
2The four, one at a time
Each one returns a resultset of exactly one row and one column. That is worth noticing: the answer is still a table, because everything MySQL returns is a table.
sum(sal), because a calculated column has no name of its own. This is precisely the situation the alias lesson was for: select sum(sal) as "Total Salary" gives it a readable heading.3They all ignore NULL
This is the single most examinable fact in the lesson. Twelve teachers, but only eleven have a salary recorded:
The total is 515000 and the average is 46818.18. Divide: 515000 ÷ 46818.18 gives 11, not 12. MySQL added up eleven salaries and divided by eleven — the NULL row was left out of both the sum and the count.
4Why the average looks like that
46818.181818181816 is an awkward thing to put in a report. The sal column is a float, and floats store fractions in binary, so a value that is not exact in binary comes back with a long tail. It is not an error and not a MySQL quirk — it is how floating-point numbers work everywhere, Python included.
The fix is to round the answer to as many places as you actually want:
round() is in the Informatics Practices syllabus rather than the Computer Science one, and it gets a full lesson later in this track. It is used here only to tidy a number; you will never be marked down for leaving an average unrounded.5Aggregates work on whatever the where left behind
An aggregate is applied after the rows have been filtered. So select avg(percent) from students where grade = 12; averages the grade-12 students only. The order is always the same: pick the rows, then aggregate what is left.
| Function | Returns | Works on | NULLs |
|---|---|---|---|
| max(col) | The largest value | Numbers, dates, text | Ignored |
| min(col) | The smallest value | Numbers, dates, text | Ignored |
| sum(col) | The total | Numbers only | Ignored |
| avg(col) | The mean | Numbers only | Ignored |
max(dob) gives the latest date — the youngest student. min(name) gives the name that comes first alphabetically. Anything that can be sorted has a largest and a smallest.6Recap
The resultset is a single row and a single column.
Not counted as zero. avg() divides by the number of real values.
Otherwise the heading is the expression, e.g. sum(sal).
max and min also work on dates and text.
A table has 12 teachers; 11 have a salary and one is NULL. The total is 515000. What does avg(sal) return?
How many rows does select max(sal) from teachers; return?
Which of these will NOT work on a text column?