AVG

Average a set of values — NULLs are excluded from both the sum and the count, not treated as zero.

Edit this pageReport an issue

Syntax

AVG(expression)
ParameterTypeNotes
expression*numeric

The values to average. Equivalent to SUM(expression) / COUNT(expression) — both skip NULL rows the same way.

What it does

SQL playground
Loading editor…
⌘/Ctrl + Enter

NULL isn't zero

SQL playground
Loading editor…
⌘/Ctrl + Enter

Customer 4 has one order of $1000. If any order's amount were NULL, AVG(amount) would still average only the non-NULL rows — it does not divide by the total row count. AVG(10, NULL, 20) is 15, not 10.

Integer division

On some engines, averaging an integer column with integer arithmetic floors the result. Cast to a decimal/float type if you need fractional precision:

AVG(CAST(quantity AS DECIMAL))  -- or AVG(quantity * 1.0)

SQLite and Postgres promote automatically for AVG(); this mostly bites on engines that do strict integer division elsewhere in the same expression.

Gotchas

  • "Average of averages" isn't the overall average unless every group has the same number of rows. Weight it: SUM(total) / SUM(count), not AVG(group_avg).
  • Outliers skew AVG more than they skew MIN/MAX/MEDIAN-style measures — a report built on AVG alone can hide a long tail.
  • Missing rows silently change the denominator. A filter that drops rows before AVG runs shrinks both the sum and the count together — the average itself may look unaffected even though the underlying data changed a lot.

Safety checklist

  • decide whether missing values should be excluded or counted as zero
  • confirm the column type doesn't force integer division
  • verify the denominator is the row set you intend (COUNT(expression) vs COUNT(*))
Was this page helpful?

On this page