sql >> Base de Datos >  >> RDS >> Mysql

MySQL uno a muchos a formato JSON

Aquí hay una consulta SQL que podría cumplir con su requisito. Utiliza Función agregada MySQL JSON_ARRAYAGG() para generar una matriz de objetos JSON (que se crean usando JSON_OBJECT() ).

Se realiza un nivel intermedio de agrupación dentro del join, para generar las sales Matriz JSON de cada usuario. Luego, los resultados se agregan en una sola línea, con una columna que contiene la 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

Demostración en DB Fiddle

Si ajusta el valor de retorno con JSON_PRETTY , la salida es la siguiente:

[
  {
    "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 :aquí hay una solución (fea) para MySQL <5.7, donde el soporte JSON no está disponible. Se basa únicamente en funciones de manipulación de cadenas. Tenga en cuenta que esto solo funcionará siempre que los campos varchar no contengan el " personaje :

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

Demostración en DB Fiddle