1

I have a table with this data

lvl1           lvl2             lvl3         item
----           ----             ----         ----
a0             b0               c0           1
a0             b0               c1           2
a0             b0               c1           3
a0             b1               c2           4
a1             b1               c3           5
a1             b2               c0           6

How can I convert it in an object tree like this?

[
  {
    id: 'a0', 
    children: [
      {
        id: 'b0',
        children: [
          {
            id: 'c0',
            items: [1]
          },
          {
            id: 'c1',
            items: [2, 3]
          }
        ]
      },
      {
        id: 'b1',
        children: [
          {
            id: 'c2',
            items: [4]
          }
        ]
      }
    ]
  },
  {
    id: 'a1', 
    children: [
      {
        id: 'b1',
        children: [
          {
            id: 'c3',
            items: [5]
          }
        ]
      },
      {
        id: 'b2',
        children: [
          {
            id: 'c0',
            items: [6]
          }
        ]
      }
    ]
  }
]

1 Answer 1

1

In a sense, the structure of the query is similar to the result:

select json_agg(children)
from (
    select 
        json_build_object(
            'id', lvl1, 
            'children', json_agg(children order by lvl1)) as children
    from (
        select 
            lvl1, 
            json_build_object(
                'id', lvl2, 
                'children', json_agg(items order by lvl2)) as children
        from (
            select 
                lvl1, 
                lvl2, 
                json_build_object(
                    'id', lvl3, 
                    'items', json_agg(item order by lvl3)) as items
            from my_table
            group by lvl1, lvl2, lvl3
            ) s
        group by lvl1, lvl2
        ) s
    group by lvl1
    ) s;

DbFiddle.

Note, that order by in the aggregates are not necessary as the order of a json array is undefined. I've added them to get exactly the expected result.

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

2 Comments

What does order by do inside json_agg?
ORDER BY in an aggregate function defines the order of the elements in the aggregated result, read about it in the documentation. You can also try to remove them and see the result. Note that the obtained json objects are equivalent.

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.