0

I have a query that outputs:-

indicator1,company1,value1
indicator1,company2,value2
indicator1,company3,value3
indicator2,company1,value4
indicator2,company2,value5
indicator2,company3,value6
....

How can I transform this output to the following json structure:-

{
 indicator1 :{
              "companies" : ["company1","company2","company3"],
              "values"    : ["value1","value2","value3"]
             },
 indicator2 :{
              "companies" : ["company1","company2","company3"],
              "values"    : ["value4","value5","value6"]
             }
}...

I'm using postgres 9.4

1 Answer 1

1

Use to_json(), json_build_object() and json_agg():

with q1 as (
    select * from 
        (values 
            ('indicator1', 'company1', 'value1'),
            ('indicator1', 'company2', 'value2'),
            ('indicator1', 'company3', 'value3'),
            ('indicator2', 'company1', 'value4'),
            ('indicator2', 'company2', 'value5'),
            ('indicator2', 'company3', 'value6')
        ) alias(ind, comp, val)
    ),
q2 as (
    select ind, to_json(array_agg(comp)) companies, to_json(array_agg(val)) "values"
    from q1
    group by 1
    order by 1
    ),
q3 as (
    select companies, "values"
    from q2
    ),
q4 as (
    select json_build_object(ind, row_to_json (q3)) obj
    from q2
    join q3 on q2.companies::text = q3.companies::text and q2."values"::text = q3."values"::text
    )
select json_agg(obj)
from q4;

Alternative compacted solution, which avoids the clumsy join condition:

with q1 as (
    select * from 
        (values 
            ('indicator1', 'company1', 'value1'),
            ('indicator1', 'company2', 'value2'),
            ('indicator1', 'company3', 'value3'),
            ('indicator2', 'company1', 'value4'),
            ('indicator2', 'company2', 'value5'),
            ('indicator2', 'company3', 'value6')
        ) alias(ind, comp, val)
    ),
q2 as (
    select ind, to_json(array_agg(comp)) companies, to_json(array_agg(val)) "values"
    from q1
    group by 1
    order by 1
    )
select json_agg(
    json_build_object(
        ind, 
        json_build_object(
            'companies', companies, 
            'values', "values")
        )
    )
from q2
Sign up to request clarification or add additional context in comments.

Comments

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.