Get only few properties from Postgres JSON column

Viewed 45

I have stored JSON data as TEXT in PostgreSQL column. Below is the format:

{"employee":[{"name":"Sunil","ph":["90","23"],"age":34},
             {"name":"Abhi","ph":["91","24"],"age":36},
             {"name":"Arnav","ph":["95","26"],"age":36}],
 "student":[{"name":"Anil","ph":["93","26"],"age":34}],
 "Admin":{"name":"Admin","ph":["90","23"],"age":36}}

Out of these properties i want to select only few fields and i am looking something like

select (value::jsonb,['name','age'])  as jsondata from details  where c.details_id =5

And output like:

{"employee":[{"name":"Sunil","age":34},{"name":"Abhi","age":36},{"name":"Arnav","age":36}],"student":[{"name":"Anil","age":34}],"Admin":{"name":"Admin","age":36}}

There are multiple fields in the JSON array but I want to select only these two. Similar to skip_nulls I am looking for something like retain_only(jsondata,['name','age']).

1 Answers

You can use jsonb_object_agg with a cross join:

select jsonb_object_agg(v.key, case when jsonb_typeof(v.value) = 'object' 
   then jsonb_build_object('name', v.value -> 'name', 'age', v.value -> 'age') 
   else (select jsonb_agg(jsonb_build_object('name', v1.value -> 'name', 
            'age', v1.value -> 'age')) 
          from jsonb_array_elements(v.value) v1) end) 
from tbl t cross join jsonb_each(t.js::jsonb) v

See fiddle.

Related