1

We have a user data that is fetched from an api(a third party) and from that data we need to store the data into a table using postgresql.

I am passing in json data from an API to the Postgres function tests. The data represents new users of my application and contains the data I want to insert into the users table (if the record does not already exist)

Below is my code.

with recursive jsondata AS(
    SELECT 
        data ->0->>'rmid' as rmid,
        data ->0->>'camid' as camid,
        data ->0->'userlist' as children 
    FROM (
        SELECT '[{"rmid":1,"camid":2,"userlist":[{"userid":34,"username":33},{"userid":35,"username":36}]},{"rmid":3,"camid":4,"userlist":[{"userid":44,"username":43},{"userid":44,"username":43}]}]'::jsonb as data
    ) s
    
    UNION 
    
    SELECT
        value ->0->> 'rmid',
        value ->0->> 'camid',
        value ->0-> 'children'
    FROM jsondata,jsonb_array_elements(jsondata.children)
    )SELECT 
    rmid,camid,
    jsonb_array_elements(children) ->> 'userid' as userid,
    jsonb_array_elements(children) ->> 'username' as username
FROM jsondata WHERE children IS NOT NULL

The output I am getting

enter image description here

The output I expect

enter image description here I need the object of the array at all the index in table, How do I achieve that?I Please help

5
  • It is not very clear what exactly is the problem. You have a table with JSONB column and you store some values in this column and then you fetch/select those values back. I don't see anything wrong here. Commented Sep 1, 2022 at 9:03
  • I need the object at index 2 of the array to get inserted in the table too. Commented Sep 1, 2022 at 9:05
  • Aren't you already inserting the whole array with all of its indexes? Commented Sep 1, 2022 at 9:08
  • data ->0->>'rmid' as rmid, data ->0->>'camid' as camid, data ->0->'userlist' as children, I am inserting only the 0th index, How do I access all the index Commented Sep 1, 2022 at 9:14
  • Just like you do with the 0th index - simply replace 0 with 2. Or, just store the whole JSON from the API. Commented Sep 1, 2022 at 9:20

1 Answer 1

2

Actually you don't need recursive query here, json processing functions are enough to achieve your desired output:

create table test(
  rmid int,
  camid int,
  userid int,
  username text
);

insert into test
select 
  (a->>'rmid')::int rmid,
  (a->>'camid')::int camid,
  (b->>'userid')::int userid,
  b->>'username' username
from (
select '[{"rmid":1,"camid":2,"userlist":[{"userid":34,"username":33},{"userid":35,"username":36}]},{"rmid":3,"camid":4,"userlist":[{"userid":44,"username":43},{"userid":44,"username":43}]}]'::jsonb as data
) j 
cross join lateral jsonb_array_elements(j.data) a
cross join lateral jsonb_array_elements(a->'userlist') b
;

select * from test;
rmid | camid | userid | username
---: | ----: | -----: | :-------
   1 |     2 |     34 | 33      
   1 |     2 |     35 | 36      
   3 |     4 |     44 | 43      
   3 |     4 |     44 | 43      

db<>fiddle here

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

2 Comments

What should I do to insert this into a table?
@NitinKumar, see the edit with the example of INSERT. I don't know what your table look like, but assuming that ids are integers you would need some casting (::int).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.