【问题标题】:How to convert result table to JSON array in MySQL如何在 MySQL 中将结果表转换为 JSON 数组
【发布时间】:2017-06-05 03:50:45
【问题描述】:

我想将结果表转换为 MySQL 中的 JSON 数组,最好只使用普通的 MySQL 命令。例如查询

SELECT name, phone FROM person;

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

预期的 JSON 输出将是

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

有没有办法在普通的 MySQL 中做到这一点?

编辑:

有一些答案如何做到这一点,例如MySQL and PHP,但我找不到纯 MySQL 解决方案。

【问题讨论】:

  • GROUP_CONCAT 和 CONCAT 的组合
  • 你是如何运行这个查询的?
  • 虽然有点晚了,但我认为答案应该已经提到了这一点,json_object 仅适用于MySQL 5.7 及更高版本
  • @toolmakersteve 干杯;我已经为那个小金块等了 2 年了
  • @Strawberry 我目前正在研究的用例是使用针对表 B 的查询结果更新表 A 中的 JSON 列。将数据格式化为 JSON 允许您在单个查询中执行此操作.

标签: mysql json etl data-conversion


【解决方案1】:

您可以使用json_object 将行获取为 JSON 对象。

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

这不会将它们放在一个数组中,也不会在它们之间放置逗号。您必须在获取它们的代码中执行此操作。

【讨论】:

  • 谢谢,这已经很近了!我仍在尝试如何从这些对象构造一个数组。
  • 我收到了这个ERROR 1305 (42000): FUNCTION mydb.JSON_OBJECT does not exist 错误。如何确保此功能存在?
  • @AnthonyKong 你用的是什么版本? json_object 只能在5.7 及更高版本中使用..
  • 我更喜欢这个而不是选择的“正确”答案,因为它将每个条目作为它自己的行返回。有了这个,您可以将结果流回来。
【解决方案2】:

新解决方案:

使用您伟大的 cmets 构建,谢谢!

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

旧解决方案:

在@Schwern 的帮助下,我设法提出了这个查询,这似乎有效!

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

【讨论】:

  • 如果您使用的是 mysql 客户端,you can use --json instead 那么它将适用于任何查询。
  • 输出可能由于 group_concat_max_len stackoverflow.com/questions/26553823/…而被截断
  • 为什么不改用JSON_ARRAY(JSON_OBJECT('name', name, 'phone', phone))
  • @DarckBlezzer 你的提议的输出似乎是一个列表的集合:[{"name": "Jack", "phone": "12345"}] [{"name": "John", "phone": "23455"}](见this example
  • @DarckBlezzer 而不是JSON_ARRAY 而不是JSON_ARRAYAGG
【解决方案3】:

JSON 有两个“分组依据”函数,称为 json_arrayagg、json_objectagg。

这个问题可以通过以下方式解决:

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

这需要 MySQL 5.7+。

【讨论】:

    【解决方案4】:

    如果你像我一样被 MySQL 5.6 困住,试试这个:

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

    【讨论】:

    • 感谢老版本mysql的解决方案
    • 应该自己转义字符串中的任何引号
    【解决方案5】:

    如果你需要一个嵌套的 JSON 数组对象,你可以加入 JSON_OBJECTjson_arrayagg 如下:

    {
        "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
            }
        ]
    }
    

    你可以这样做:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-23
      • 2015-11-25
      • 1970-01-01
      • 2017-02-05
      相关资源
      最近更新 更多