Re: Extracting data from jsonb array? - Mailing list pgsql-general

From Ken Tanzer
Subject Re: Extracting data from jsonb array?
Date
Msg-id CAD3a31XxwRS8cXT+wBQCdr=Urug0rRe_RCTQ9ATS=RXNLr4zDA@mail.gmail.com
Whole thread Raw
In response to Re: Extracting data from jsonb array?  (Rob Sargent <robjsargent@gmail.com>)
Responses Re: Extracting data from jsonb array?
List pgsql-general


On Mon, Dec 7, 2020 at 5:20 PM Rob Sargent <robjsargent@gmail.com> wrote:


On 12/7/20 6:17 PM, David G. Johnston wrote:
On Mon, Dec 7, 2020 at 6:13 PM Rob Sargent <robjsargent@gmail.com> wrote:


postgres=# select id, array_agg(fa) from (select id, (jsonb_array_elements(js)->'key') as fa from foo) g group by id order by id;
 id |          array_agg          
----+------------------------------
  1 | {"\"r1kval\"","\"r1kval2\""}
  2 | {"\"r2kval\"","\"r2kval2\""}
(2 rows)

I think the quotes are a fault of example data?  

The quotes are the fault of the query author choosing the "->" operator instead of "->>".

David J.
With that correction OP might have an answer?

Thank you Rob!  I would say yes, except I fear I over-simplified my example.  What if there are other fields in the table, and I want to treat this array_agg as just another field?  So here's the query you had (with the ->> change):

=> select id, array_agg(fa) from (select id, (jsonb_array_elements(js)->>'key') as fa from foo) g group by id;
 id |    array_agg    
----+------------------
  1 | {r1kval,r1kval2}
  2 | {r2kval,r2kval2}
(2 rows)


And here's the table/data with two other fields added, f1 & f2:

CREATE TEMP TABLE foo (
  id INTEGER PRIMARY KEY,
  f1  TEXT,
  f2  TEXT,
  js  JSONB
);
INSERT INTO foo (id,f1,f2,js) VALUES (1,'My Text 1','My Text 1a',
'[
{"key":"r1kval","key2":"r1k2val"},
{"key":"r1kval2","key2":"r1k2val2"}
]');
INSERT INTO foo (id,f1,f2,js) VALUES (2,'My Text 2','My Text 2a',
'[
{"key":"r2kval","key2":"r2k2val"},
{"key":"r2kval2","key2":"r2k2val2"}
]');


If I want all 4 of my fields, all I can think to do is join your query back to the table.  Something like this:

=> SELECT id,f1,f2,array_agg AS vals FROM foo LEFT JOIN (select id, array_agg(fa) from (select id, (jsonb_array_elements(js)->>'key') as fa from foo) g group by id) foo2 USING (id);

 id |    f1     |     f2     |       vals      
----+-----------+------------+------------------
  1 | My Text 1 | My Text 1a | {r1kval,r1kval2}
  2 | My Text 2 | My Text 2a | {r2kval,r2kval2}
(2 rows)

That seems to work, but is there any other way to streamline or simplify that?

Cumbersome is in the eyes of the beholder ;)  

Maybe.  There's probably an aesthetic component, but also an aspect that can be quantified, likely in character counts. :)

I'm of course very glad Postgresql has the ability to work with JSON at all, but as I dig into it I'm kinda surprised at the level of complexity needed to extract data in relatively simple ways.  Hopefully eventually it will seem simple to me, as it seems to appear to others.

Cheers,
Ken


--
AGENCY Software  
A Free Software data system
By and for non-profits
(253) 245-3801

learn more about AGENCY or
follow the discussion.

pgsql-general by date:

Previous
From: Rob Sargent
Date:
Subject: Re: Extracting data from jsonb array?
Next
From: "David G. Johnston"
Date:
Subject: Re: Extracting data from jsonb array?