En MariaDB, JSON_OBJECTAGG()
es una función integrada que devuelve un objeto JSON que contiene pares clave-valor, en función de sus dos argumentos.
Sintaxis
La sintaxis es así:
JSON_OBJECTAGG(key, value)
La función acepta dos expresiones que se evalúan como un solo valor, o dos nombres de columna, como argumentos. El primer argumento es la clave y el segundo es su valor.
Ejemplo
Aquí hay un ejemplo simple para demostrarlo:
SELECT JSON_OBJECTAGG("name", "Homer");
Resultado:
+---------------------------------+ | JSON_OBJECTAGG("name", "Homer") | +---------------------------------+ | {"name":"Homer"} | +---------------------------------+
Aunque este ejemplo demuestra cómo funciona la función, el beneficio real se presenta cuando se trabaja con columnas u otras expresiones.
A continuación se muestran ejemplos que utilizan columnas de base de datos para los argumentos.
Un ejemplo de base de datos
Supongamos que consultamos una tabla:
SELECT
PetName,
DOB
FROM Pets;
Y obtenga el siguiente conjunto de resultados:
+---------+------------+ | PetName | DOB | +---------+------------+ | Fluffy | 2020-11-20 | | Fetch | 2019-08-16 | | Scratch | 2018-10-01 | | Wag | 2020-03-15 | | Tweet | 2020-11-28 | | Fluffy | 2020-09-17 | | Bark | NULL | | Meow | NULL | +---------+------------+
Ahora ejecutemos una consulta que pase cada columna a JSON_OBJECTAGG()
función, para que los resultados se devuelvan como un objeto JSON:
SELECT JSON_OBJECTAGG(PetName, DOB)
FROM Pets
WHERE DOB < '2020-04-01';
Resultado:
+--------------------------------------------------------------------+ | JSON_OBJECTAGG(PetName, DOB) | +--------------------------------------------------------------------+ | {"Fetch":"2019-08-16", "Scratch":"2018-10-01", "Wag":"2020-03-15"} | +--------------------------------------------------------------------+
Todo lo que hicimos fue pasar los nombres de las columnas a JSON_OBJECTAGG()
función.
También usamos un WHERE
cláusula para reducir un poco los resultados.
Resultados agrupados
Podemos usar el SQL GROUP BY
cláusula para producir objetos JSON basados en una agrupación de otra columna.
Supongamos que agregamos una columna a nuestra consulta original:
SELECT
PetTypeId,
PetName,
DOB
FROM Pets;
Resultado:
+-----------+---------+------------+ | PetTypeId | PetName | DOB | +-----------+---------+------------+ | 2 | Fluffy | 2020-11-20 | | 3 | Fetch | 2019-08-16 | | 2 | Scratch | 2018-10-01 | | 3 | Wag | 2020-03-15 | | 1 | Tweet | 2020-11-28 | | 3 | Fluffy | 2020-09-17 | | 3 | Bark | NULL | | 2 | Meow | NULL | +-----------+---------+------------+
Ahora tenemos un PetTypeId
columna así como el PetName
y DOB
columnas Esto hace coincidir un tipo de mascota con cada mascota.
Aquí hay un ejemplo del uso de GROUP BY
cláusula para agrupar nuestros resultados por el PetTypeId
columna mientras usa JSON_OBJECTAGG()
función:
SELECT
PetTypeId,
JSON_OBJECTAGG(PetName, DOB)
FROM Pets
GROUP BY PetTypeId;
Resultado:
+-----------+--------------------------------------------------------------------------------+ | PetTypeId | JSON_OBJECTAGG(PetName, DOB) | +-----------+--------------------------------------------------------------------------------+ | 1 | {"Tweet":"2020-11-28"} | | 2 | {"Fluffy":"2020-11-20", "Scratch":"2018-10-01", "Meow":null} | | 3 | {"Fetch":"2019-08-16", "Wag":"2020-03-15", "Fluffy":"2020-09-17", "Bark":null} | +-----------+--------------------------------------------------------------------------------+
Esto nos permitió crear un objeto JSON separado para cada tipo de mascota.
La siguiente consulta usa un INNER JOIN
en otra tabla para devolver el tipo de mascota real, no solo la ID.
SELECT
pt.PetType,
p.PetName,
p.DOB
FROM Pets p
INNER JOIN PetTypes pt
ON pt.PetTypeId = p.PetTypeId
ORDER BY PetType;
Resultado:
+---------+---------+------------+ | PetType | PetName | DOB | +---------+---------+------------+ | Bird | Tweet | 2020-11-28 | | Cat | Scratch | 2018-10-01 | | Cat | Fluffy | 2020-11-20 | | Cat | Meow | NULL | | Dog | Wag | 2020-03-15 | | Dog | Fetch | 2019-08-16 | | Dog | Bark | NULL | | Dog | Fluffy | 2020-09-17 | +---------+---------+------------+
Podemos ver que el tipo de mascota real ahora aparece en la primera columna, en lugar de solo la identificación del tipo de mascota.
Ahora usemos el JSON_OBJECTAGG()
función:
SELECT
pt.PetType,
JSON_OBJECTAGG(p.PetName, p.DOB)
FROM Pets p
INNER JOIN PetTypes pt
ON pt.PetTypeId = p.PetTypeId
GROUP BY pt.PetType;
Resultado:
+---------+--------------------------------------------------------------------------------+ | PetType | JSON_OBJECTAGG(p.PetName, p.DOB) | +---------+--------------------------------------------------------------------------------+ | Bird | {"Tweet":"2020-11-28"} | | Cat | {"Scratch":"2018-10-01", "Fluffy":"2020-11-20", "Meow":null} | | Dog | {"Wag":"2020-03-15", "Fetch":"2019-08-16", "Bark":null, "Fluffy":"2020-09-17"} | +---------+--------------------------------------------------------------------------------+