How to convert result table to JSON array in MySQL

MysqlJsonEtlData Conversion

Mysql Problem Overview


I'd like to convert result table to JSON array in MySQL using preferably only plain MySQL commands. For example with query

SELECT name, phone FROM person;

| name | phone |
| Jack | 12345 |
| John | 23455 |

the expected JSON output would be

[  {    "name": "Jack",    "phone": 12345  },  {    "name": "John",    "phone": 23455  }]

Is there way to do that in plain MySQL?

EDIT:

There are some answers how to do this with e.g. MySQL and PHP, but I couldn't find pure MySQL solution.

Mysql Solutions


Solution 1 - Mysql

New solution:

Built using Your great comments, thanks!

SELECT JSON_ARRAYAGG(JSON_OBJECT('name', name, 'phone', phone)) from Person;

Old solution:

With help from @Schwern I managed to put up this query, which seems to work!

SELECT CONCAT(
    '[', 
    GROUP_CONCAT(JSON_OBJECT('name', name, 'phone', phone)),
    ']'
) 
FROM person;

Solution 2 - Mysql

You can use json_object to get rows as JSON objects.

SELECT json_object('name', name, 'phone', phone)
FROM person;

This won't put them in an array, or put commas between them. You'll have to do that in the code which is fetching them.

Solution 3 - Mysql

If you're stuck on MySQL 5.6 like me, try this:

SELECT
    CONCAT(
       '[',
       GROUP_CONCAT(
           CONCAT(
               '{"name":"', name, '"',
               ',"phone":"', phone, '"}'
           )
       ),
       ']'
    ) as json
FROM person

Solution 4 - Mysql

There are two "group by" functions for JSON called json_arrayagg, json_objectagg.

This problem can be solved with:

SELECT json_arrayagg(
    json_merge(
          json_object('name', name), 
          json_object('phone', phone)
    )
) FROM person;

This requires MySQL 5.7+.

Solution 5 - Mysql

If u need a nested JSON Array Object, u can join JSON_OBJECT with json_arrayagg as below:

{
    "nome": "Moon",
    "resumo": "This is a resume.",
    "dt_inicial": "2018-09-01",
    "v.dt_final": null,
    "data": [
        {
            "unidade": "unit_1",
            "id_unidade": 9310
        },
        {
            "unidade": "unit_2",
            "id_unidade": 11290
        },
        {
            "unidade": "unit_3",
            "id_unidade": 13544
        },
        {
            "unidade": "unit_4",
            "id_unidade": 13608
        }
    ]
}

U cand do like this:

CREATE DEFINER=`root`@`localhost` PROCEDURE `get_lst_caso`(
IN `codigo` int,
IN `cod_base` int)
BEGIN

	DECLARE json TEXT DEFAULT '';

	SELECT JSON_OBJECT(
		'nome', v.nome, 
		'dt_inicial', v.dt_inicial, 
		'v.dt_final', v.dt_final, 
		'resumo', v.resumo,
		'data', ( select json_arrayagg(json_object(
								'id_unidade',`tb_unidades`.`id_unidade`,
								'unidade',`tb_unidades`.`unidade`))
							from tb_caso_unidade
								INNER JOIN tb_unidades ON tb_caso_unidade.cod_unidade = tb_unidades.id_unidade
							WHERE tb_caso_unidade.cod_caso = codigo)
	) INTO json
	FROM v_caso AS v
	WHERE v.codigo = codigo and v.cod_base = cod_base;
	
	SELECT json;
	
END

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionronkotView Question on Stackoverflow
Solution 1 - MysqlronkotView Answer on Stackoverflow
Solution 2 - MysqlSchwernView Answer on Stackoverflow
Solution 3 - MysqlBrendanView Answer on Stackoverflow
Solution 4 - MysqlmikeryderView Answer on Stackoverflow
Solution 5 - MysqlJuliano CostaView Answer on Stackoverflow