sqljsondatabasepostgresql

postgres - How to parse json array elements?


PostgreSQL 15.4

Below is the postgres table table1:

CREATE TABLE table1 (
 id INT PRIMARY KEY,
 name TEXT,
 skills JSON
);

with below rows inserted:

INSERT INTO table1 (id, name, skills) VALUES
 (1, 'Alice', ‘[
                 {“sid" : 11, "description" : “Cardio"}, 
                 {"sid" : 13, "description" : “Anesthist"}
              ]'
 ),
 (2, ‘Bob', ‘[
               {“sid" : 10, "description" : “Gastro"}, 
               {"sid" : 9, "description" : “Oncology"}
              ]’
 ),
 (3, ‘Sam', ‘[
              ]’
 );

Below is the desired output, upon running select query:

id   name     skill
---------------------
1   Alice     [“Cardio”,“Anestisht”]
2   Bob       ["Gastro","Oncology"]
3   Sam       []

where skill column is TEXT type


Tried below query

select  
id, name, d ->> 'description' as skill 
from table1, 
json_array_elements(skills) as d

that gives duplicate rows(as shown below) with a missing row, which is incorrect

id   name     skill
---------------------
1   Alice     Cardio
1   Alice     Anestisht
2   Bob       Gastro
2   Bob       Oncology

Solution

  • Use array_agg() to aggregate the descriptions into an array:

    select
      id,
      name,
      array_agg(skill ->> 'description') as skill
    from table1, json_array_elements(skills) AS skill
    group by 1, 2
    

    See live demo.


    To return rows for people with no skills as well, here's one way:

      id,
      name,
      array_agg(skill ->> 'description')
    from table1, json_array_elements(skills) AS skill
    group by 1, 2
    union all
    select
      id,
      name,
      array[]::text[]
    from table1
    where json_array_length(skills) = 0
    

    See live demo.