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).

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.