avg
Available in all SQLite versions.→ REALReturns the average value of all non-NULL values of X within a group. String and BLOB values that do not look like numbers are interpreted as 0. The result is always a floating-point value when at least one non-NULL input exists. Returns NULL if there are no non-NULL inputs.
Signatures
avg(X)avg(DISTINCT X)Parameters
| Parameter | Type | Description |
|---|---|---|
| X | numeric | The value to average. NULL values are ignored. Non-numeric strings and BLOBs are treated as 0. |
Examples
Average price of all products
SELECT avg(price) FROM products;24.99Average price per category
SELECT category, avg(price) FROM products GROUP BY category;Electronics: 349.50, Books: 19.99Average test score for a specific student
SELECT avg(score) FROM test_results WHERE student_id = 42;87.5Average of distinct salaries only
SELECT avg(DISTINCT salary) FROM employees WHERE dept = 'Engineering';95000.0Average API response time over the last 7 days
SELECT avg(response_ms) FROM api_logs WHERE endpoint = '/api/search' AND created_at >= date('now','-7 days');142.3When a column contains a mix of NULL and 0, avg() excludes NULLs from the count of rows used as the denominator, but includes rows where the value is 0. This means avg(score) over [90, 0, NULL] returns 45.0 (two rows), not 30.0 (three rows). Developers often expect NULLs to be treated as zero, leading to an inflated average. The silent coercion of non-numeric strings to 0 compounds this: a stray empty string lowers the average without any error.
✓ Instead: Use COALESCE before aggregating when zero and NULL should be treated identically: avg(COALESCE(score, 0)).
If no rows match your WHERE clause, avg() returns NULL, not 0. Use COALESCE(avg(X), 0) when a zero default is more useful than NULL — for example when displaying metrics in a dashboard where NULL would break downstream arithmetic.
In both SQLite and PostgreSQL, avg() ignores NULLs and returns NULL when all inputs are NULL (empty group). The key SQLite-specific behavior is that non-numeric strings are silently coerced to 0 rather than raising an error, which PostgreSQL would reject with a type error. PostgreSQL's avg() preserves exact numeric precision for integer inputs (returning NUMERIC), whereas SQLite always returns REAL (IEEE 754 float).