1

I want to calculate the average from multiple (json) arrays in Postgres.

I have the following table:

CREATE TABLE marks (student varchar(48), year int , testresult json);

INSERT INTO marks 
VALUES ('John',2017,'[7.3,8.1,9.2]'),
      ('Mary', 2017, '[6.1,7.4,5.6]'), 
     ('Tim',2017,'[6.3,5.6,8.3]');

There are 3 students in 2017 that all have taken 3 tests. I want to calculate the average of the tests for all students in 2017 (with n precision).

Have tried it myself, and only achieved the following until now: http://www.sqlfiddle.com/#!15/58f38/44

So I want to get the following result:

student|  year | averages   
-------+-------+-----------
All    |  2017 | [6.567, 7.033, 7.700]

1 Answer 1

1

You could use unnest, do calculation and aggregate back to JSON format:

WITH cte AS (
   SELECT 'All' AS student, year, AVG(unnest::decimal(10,2)) AS av
   FROM marks,
   unnest(ARRAY(SELECT json_array_elements_text(testresult))) with ordinality
   GROUP BY year, ordinality
)
SELECT student, year, array_to_json(array_agg(av::decimal(10,3))) AS averages
FROM cte
GROUP BY student, year;

Output:

+---------+------+---------------------+
| student | year |      averages       |
+---------+------+---------------------+
| All     | 2017 | [6.567,7.033,7.700] |
+---------+------+---------------------+

DBFiddle Demo

Sign up to request clarification or add additional context in comments.

9 Comments

Great! Thanks for your fast and helpful answer. So as I understand correctly, the array is split and the ordinality keeps the original order? And then the averages are concatenated to a new array again?
@web_student Yes, exactly.
I have tried this query and it works. Expect when I try I it with a large dataset (30K+ records) and when the averages json column contains a large json array (60k+ elements) I can't execute the query, getting the following error: invalid memory alloc request size. Is this only due to the large size of the dataset?
@web_student Well, number of rows matters.
i believe you should also have an "order by ordinality"
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.