Search code examples
sqlarraysjsonpostgresqlpostgresql-10

ERROR: cannot deconstruct an array as an object


This question is the follow-up of this

I have the following table with sample records:

create table jtest
(
    id int,
    jcol json
);

insert into jtest values(1,'[{"name":"Jack","address1":"HNO 123"}]');
insert into jtest values(1,'[{"address2":"STREET1"}]');
insert into jtest values(1,'[{"address3":"UK"}]');

select * from jtest;

id      jcol
-------------------------------------------
1       [{"name":"Jack","address":"HNO 123 UK"}]
1       [{"address2":"STREET1"}]
1       [{"address3":"UK"}]

Expected result:

id      jcol
--------------------------------------------------------------------------------------------
1       [{"name":"Jack","address":"HNO 123 UK", "address2":"STREET1", "address3":"UK"}]

Tried the following query:

select id,json_agg(jcol) as jcol 
from jtest
group by id;

But getting result is unexpected:

id      jcol
--------------------------------------------------------------------------------------------
1       [[{"name":"Jack","address":"HNO 123 UK"}], [{"address2":"STREET1"}], [{"address3":"UK"}]]   

Tried with S-Man answer:

SELECT
    id,
    json_object_agg(key, value)  
FROM
    jtest,
    json_each(jcol)              
GROUP BY id;

Getting an error:

ERROR: cannot deconstruct an array as an object


Solution

  • If all of your arrays contain a single object, as showed in your sample data, you can do:

    select t.id, jsonb_build_array(json_object_agg(x.k, x.v))
    from jtest t
    cross join lateral json_each(t.jcol -> 0) as x(k, v)            
    group by t.id;
    

    That's basically the same logic as your original code, excepted that it fetches the first (only) object in the array before json_each().