MySQL json_object and json_arrayagg with group by not working as expected

I’ve a many to many relationship with this tables

Table assets:

id name other fields
19 asset 1
20 asset 2

Branches table:

id name other fields
1 branch 1
2 branch 2

branch_r_asset:

branch_id asset_id
1 1
1 2
2 14
n n

I want to return a json object in this form:

{
  'branches' : [
    {
      'branch_id': 1,
      'branch_name': 'branch 1',
      'branch_children': [
        {
          'asset_id': 1,
          'asset_name': 'asset 1'
        },
        {
          'asset_id': 2,
          'asset_name': 'asset 2'
        },
        {
          'asset_id': 99999,
          'asset_name': 'asset 99999'
        }
      ]
    },
    {
      'branch_id': 2,
      'branch_name': 'branch 2',
      'branch_children': [
        {
          'asset_id': 1,
          'asset_name': 'asset 1'
        },
        {
          'asset_id': 2,
          'asset_name': 'asset 2'
        },
        {
          'asset_id': 99999,
          'asset_name': 'asset 99999'
        }
      ]
    }
  ]
}

The children could be arrays or objects. It’s indistinct for the example.

With this script:

select json_object(
  'branch_id', branches.id,
  'branch_name', branches.name,
  'branch_children', json_arrayagg(json_object('asset_id', list.asset_id, 'asset_name', list.asset_name))
)
from branches
left join (
  select b.id as branch_id, a.id as asset_id, a.name as asset_name
  from branch_r_asset ba
  join branches b
    on b.id = ba.branch_id
  join assets a
    on a.id = ba.asset_id
  group by b.id
) list on list.branch_id = branches.id
group by branches.id;

I’m getting the results but separated in rows for each branch_id I have in the table like this:

{"branch_name": "branch 1", "branch_id": "1", "branch_children": [{"asset_name": "asset 1", "asset_id": "1" }, {"asset_name": "asset 2", "asset_id": "2" }]}

{"branch_name": "branch 2", "branch_id": "2", "branch_children": [{"asset_name": "asset 15", "asset_id": "15" }, {"asset_name": "asset 244", "asset_id": "244" }, {"asset_name": "asset 7", "asset_id": "7" }]}

{"branch_name": "branch 3", "branch_id": "3", "branch_children": [{"asset_name": "asset 12", "asset_id": "12" }}]}

I’m not sure if it’s json managing problem (by me) or a group function.

Thanks in advance.

>Solution :

select json_object(
  'branches', json_arrayagg(
    json_object(
      'branch_id', branch_id,
      'branch_name', branch_name,
      'branch_children', branch_children)
    )
  )
)
from (
  select b.id as branch_id, b.name as branch_name, 
    json_arrayagg(
      json_object(
        'asset_id', a.id, 
        'asset_name', a.name
      )
    ) as branch_children
  from branches b
  left join branch_r_asset ba
    on b.id = ba.branch_id
  left join assets a
    on a.id = ba.asset_id
  group by b.id
) as t

Leave a Reply