当前位置: 首页 > 面试题库 >

如何使用mysql本地json函数生成嵌套的json对象?

温源
2023-03-14
问题内容

我试图在MySQL
5.7.12版(本手册的13.16节)中仅使用本机JSON功能(无PHP等),我试图编写一个查询以从包含子对象的关系表中生成JSON文档。给出以下示例:

CREATE TABLE `parent_table` (
   `id` int(11) NOT NULL,
   `desc` varchar(20) NOT NULL,
   PRIMARY KEY (`id`)
);
CREATE TABLE `child_table` (
   `id` int(11) NOT NULL,
   `parent_id` int(11) NOT NULL,
   `desc` varchar(20) NOT NULL,
   PRIMARY KEY (`id`,`parent_id`)
);
insert `parent_table` values (1,'parent row 1');
insert `child_table` values (1,1,'child row 1');
insert `child_table` values (2,1,'child row 2');

我正在尝试生成如下所示的JSON文档:

[{
    "id" : 1,
    "desc" : "parent row 1",
    "child_objects" : [{
            "id" : 1,
            "parent_id" : 1,
            "desc" : "child row 1"
        }, {
            "id" : 2,
            "parent_id" : 1,
            "desc" : "child row 2"
        }
    ]
}]

我是MySQL的新手,并且怀疑有一种SQL模式可以从一对多关系生成嵌套的JSON对象,但是我很难找到它。

在Microsoft SQL(我更熟悉)中,它的工作原理如下:

select 
 [p].[id]
,[p].[desc]
,(select * from [dbo].[child_table] where [parent_id] = [p].[id] for json auto) AS [child_objects]
from [dbo].[parent_table] [p]
for json path

我试图在MySQL中编写等效的代码,如下所示:

select json_object(
 'id',p.id 
,'desc',p.`desc`
,'child_objects',(select json_object('id',id,'parent_id',parent_id,'desc',`desc`) 
                  from child_table where parent_id = p.id)
)
from parent_table p;

select json_object(
  'id',p.id 
 ,'desc',p.`desc`
 ,'child_objects',json_array((select json_object('id',id,'parent_id',parent_id,'desc',`desc`) 
                              from child_table where parent_id = p.id))
 )
 from parent_table p

两次尝试均失败,并出现以下错误:

Error Code: 1242. Subquery returns more than 1 row

问题答案:

出现这些错误的原因是父json对象不希望将结果集作为其输入之一,因此您需要具有简单的对象对,例如{name,string}等错误报告-
将来的功能中可能会提供
..
。这只是意味着您需要将多行结果转换为用逗号分隔的结果隐式形式,然后转换为json数组。

您的第二个示例几乎可以理解。

您可以使用GROUP_CONCAT函数来实现自己的目标

select json_object(
  'id',p.id 
 ,'desc',p.`desc`
 ,'child_objects',json_array(
                     (select GROUP_CONCAT(
                                 json_object('id',id,'parent_id',parent_id,'desc',`desc`)
                             )   
                      from child_table 
                      where parent_id = p.id))
                   )
 from parent_table p;

这几乎可以正常工作,最终将子查询视为一个字符串,从而在其中保留了转义字符。

'{\"id\": 1, 
\"desc\": \"parent row 1\", 
\"child_objects\": 
    [\"
    {\\\"id\\\": 1,
     \\\"desc\\\": \\\"child row 1\\\", 
    \\\"parent_id\\\": 1
    },
    {\\\"id\\\": 2, 
    \\\"desc\\\": \\\"child row 2\\\", 
    \\\"parent_id\\\": 1}\"
    ]
}'

为了使它以适当的格式工作,您需要更改创建JSON输出的方式,如下所示:

select json_object(
  'id',p.id 
 ,'desc',p.`desc`
 ,'child_objects',(select CAST(CONCAT('[',
                GROUP_CONCAT(
                  JSON_OBJECT(
                    'id',id,'parent_id',parent_id,'desc',`desc`)),
                ']')
         AS JSON) from child_table where parent_id = p.id)

 ) from parent_table p;

这将为您提供所需的确切结果:

'{\"id\": 1, 
\"desc\": \"parent row 1\", 
\"child_objects\": 
    [{\"id\": 1, 
    \"desc\": \"child row 1\", 
    \"parent_id\": 1
    }, 
    {\"id\": 2, 
    \"desc\": \"child row 2\", 
    \"parent_id\": 1
    }]  
}'


 类似资料:
  • 如何使用jolt转换将平面JSON转换为嵌套JSON?我对JSON和jolt是新手。 输入: 预期输出: 编辑:我想在< code>SubFunds中添加一个新字段,但是新字段不在JSON文件中,它是计算字段,我可以按原样添加示例吗 并重命名字段:

  • 我想从API中获取countynames,它返回嵌套对象; 等等,有200多个国家,每个县都有自己的“编号”。最后,我想列出所有“姓名”信息。我想我应该使用JsonDeserializer,但不幸的是我不能。

  • 我有一个带有嵌套字段的JSON: 我正在使用JSONPATH从嵌套中获取。 我已经将我的JSON文本粘贴到了http://jsonpath.com/这个网站上;并且在使用了这一行之后: 我得到了这个: 使用此行后: 我得到了这个: 我尝试返回(输出)的内容如下: 但是我找不到合适的语法来将这两个组合在一行中,并用一个JSONPATH查询返回它们。

  • 问题内容: 我正在尝试使用HTTPie进行分析以发送一些嵌套的JSON对象,但我找不到方法。很清楚如何发送JSON对象,而不发送嵌套对象,例如 {“ user”:{“ name”:“ john”“ age”:10}} 问题答案: 您可以通过传递整个JSON: 或者使用以下命令将原始JSON指定为值:

  • 问题内容: 此问题特定于从[GitHub Repo使用:flatten](https://github.com/amirziai/flatten) 该软件包位于pypi flatten-json 0.1.7上,可以与 此问题特定于软件包的以下组件: 使用递归展平嵌套 用Python递归思考 在Python中展平JSON对象 嵌套如何?: 已用于解压缩最终超过100000列的文件 展平的JSON是否

  • 问题内容: 我需要从查询创建一个JSON输出,该查询使用具有一对多关系的两个表之间的内部联接。 我希望将辅助表的值作为主表的数组属性嵌套。 考虑以下示例: 并查询: 这将打印以下JSON: 但是,我希望将pets数据作为所有者数据中的数组存储: 我怎样才能做到这一点? 问题答案: 您可以使用以下查询: