Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MySQL um-para-muitos para formato JSON


Aqui está uma consulta SQL que pode atender ao seu requisito. Ela usa Função agregada MySQL JSON_ARRAYAGG() para gerar uma matriz de objetos JSON (que são criados usando JSON_OBJECT() ).

Um nível intermediário de agrupamento é realizado dentro da junção, para gerar as sales Matriz JSON de cada usuário. Em seguida, os resultados são agregados em uma única linha, com uma coluna que contém a matriz de objetos JSON resultante.
SELECT
  JSON_ARRAYAGG(JSON_OBJECT('id', u.id, 'name', u.name, 'sales', s.sales))
FROM
    user u
    LEFT JOIN (
        SELECT 
            user, 
            JSON_ARRAYAGG(JSON_OBJECT('id', id, 'item', item)) sales 
        FROM sale 
        GROUP BY user
    ) s ON s.user = u.id

Demonstração no DB Fiddle

Se você envolver o valor de retorno com JSON_PRETTY , a saída é a seguinte:
[
  {
    "id": 1,
    "name": "User 1",
    "sales": [
      {
        "id": 1,
        "item": "t-shirt"
      },
      {
        "id": 2,
        "item": "jeans"
      }
    ]
  },
  {
    "id": 2,
    "name": "User 2",
    "sales": [
      {
        "id": 3,
        "item": "sweatpants"
      },
      {
        "id": 4,
        "item": "gloves"
      }
    ]
  }
]

Editar :aqui está uma solução (feia) para MySQL <5.7, onde o suporte JSON não está disponível. Ele se baseia apenas em funções de manipulação de strings. Observe que isso só funcionará desde que os campos varchar não contenham o " personagem :
SELECT
    CONCAT(
        '[', 
        GROUP_CONCAT( CONCAT( '{ "id":', u.id, ', "name":"', u.name, '", "sales":', s.sales, ' }' )  SEPARATOR ', ' ),
        ']'
    )
FROM 
    user u
    LEFT JOIN (
        SELECT 
            user, 
            CONCAT( 
               '[', 
                GROUP_CONCAT( CONCAT( '{ "id":', id, ', "item":"', item, '" }' ) SEPARATOR ', '),
                ']'
            ) sales 
    FROM sale
    GROUP BY user ) s ON s.user = u.id

Demonstração no DB Fiddle