1

Given data like the below:

+---+------------+------------
|id | change     | date       
+---+------------+------------
| 1 | name       | 2018-06-20
| 2 | address    | 2018-06-20
| 3 | email      | 2018-06-20
| 4 | email      | 2018-06-21
| 5 | address    | 2018-06-22
| 6 | address    | 2018-06-23

I'm trying to create a view that summarises the above into a single json column with data like:

{"name":["2018-06-20"], "address":["2018-06-20","2018-06-22","2018-06-23"], "email":["2018-06-20","2018-06-21"]} 

I have been trying to figure it out using the array_aggr, array_to_json, json_agg, array_build_object functions but I can't seem to get it quite right.

I hope someone can help.

Cheers

1 Answer 1

1

You should use jsonb aggregates twice for two levels:

select jsonb_pretty(jsonb_object_agg(change, dates))
from (
    select change, jsonb_agg(date) as dates
    from my_table
    group by change
    ) s

     jsonb_pretty      
-----------------------
 {                    +
     "name": [        +
         "2018-06-20" +
     ],               +
     "email": [       +
         "2018-06-20",+
         "2018-06-21" +
     ],               +
     "address": [     +
         "2018-06-20",+
         "2018-06-22",+
         "2018-06-23" +
     ]                +
 }
(1 row) 

Note that jsonb_pretty() is unnecessary, used only for a nice output.

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

2 Comments

Thanks! I thought I read somewhere that you couldn't nest agg functions. I must have misunderstood.
You cannot directly nest aggregates, this is impossible: jsonb_object_agg(change, jsonb_agg(data)) -- ERROR. You have to use a derived table (or CTE) like in the answer.

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.