patternsqlMinor
Calculating average with AVG for a list of numbers
Viewed 0 times
withavgnumbersaveragecalculatingforlist
Problem
This is probably a newbie question (bear with me) but how can I calculate the average for a list of numbers using SQL and the
like:
How can I calculate the average of
I have tried different kinds of variations like:
but:
ERROR: syntax error at or near "select"
I just can't seem to find the right syntax. I'm on PostgreSQL at the moment if it matters.
AVG function? I mean, I can add together numbers in SQL like:
SELECT 2+3+4How can I calculate the average of
2, 3 and 4 without inserting them to a table first?I have tried different kinds of variations like:
SELECT 2 AS foo UNION 3 AS foo UNION 4 AS foo
foo
integer
1 2
2 3
3 4but:
SELECT AVG(SELECT 2 AS foo UNION 3 AS foo UNION 4 AS foo)ERROR: syntax error at or near "select"
I just can't seem to find the right syntax. I'm on PostgreSQL at the moment if it matters.
Solution
The best solution depends on where and in what form the values come from.
Use the set returning function
Which is short syntax for:
Alternatively, use a
You can do the same with a much more verbose chain of
Use
SQL Fiddle.
Note that all numeric literals in the example are cast to
floating-point argument, otherwise the same as the argument data type
unnest()Use the set returning function
unnest() with an array in the FROM clause. That's shortest for long lists, but it's a Postgres specific solution.SELECT avg(n) FROM unnest('{2,3,4}'::int[]) n;Which is short syntax for:
SELECT avg(n) FROM unnest('{2,3,4}'::int[]) AS n(n);VALUESAlternatively, use a
VALUES expression as subquery. This is standard SQL.SELECT avg(n)
FROM (VALUES (2),(3),(4)) t(n);UNION ALLYou can do the same with a much more verbose chain of
SELECT ... UNION ALL SELECT .... Also standard SQL.SELECT avg(n)
FROM (
SELECT 2
UNION ALL
SELECT 3
UNION ALL
SELECT 4
) t(n);Use
UNION ALL, not just UNION, which would fold duplicates (which you did not specify!) and is therefore also considerably more expensive.SQL Fiddle.
Note that all numeric literals in the example are cast to
integer automatically (just digits). For other data types you may have to add explicit type casts. avg() returns (per documentation):numeric for any integer-type argument, double precision for afloating-point argument, otherwise the same as the argument data type
Code Snippets
SELECT avg(n) FROM unnest('{2,3,4}'::int[]) n;SELECT avg(n) FROM unnest('{2,3,4}'::int[]) AS n(n);SELECT avg(n)
FROM (VALUES (2),(3),(4)) t(n);SELECT avg(n)
FROM (
SELECT 2
UNION ALL
SELECT 3
UNION ALL
SELECT 4
) t(n);Context
StackExchange Database Administrators Q#77005, answer score: 7
Revisions (0)
No revisions yet.