如何使用mysql本地json函数生成嵌套的json对象? [英] How do I generate nested json objects using mysql native json functions?

查看:179
本文介绍了如何使用mysql本地json函数生成嵌套的json对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Using only the native JSON fuctions (no PHP, etc) in MySQL version 5.7.12 (section 13.16 in the manual) I am trying to write a query to generate a JSON document from relational tables that contains a sub object. Given the following example:

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文档:

I am trying to generate a JSON document that looks like this:

[{
    "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对象,但是我很难找到它.

I am new to MySQL and suspect there is a SQL pattern for generating nested JSON objects from one to many relationships but I'm having trouble finding it.

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

In Microsoft SQL (which I'm more familiar with) the following works:

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中编写等效的代码,如下所示:

I attempted to write the equivalent in MySQL as follows:

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

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

Both attempts fail with the following error:

Error Code: 1242. Subquery returns more than 1 row

推荐答案

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

The reason you are getting these errors is that the parent json object is not expecting a result set as one of its inputs, you need to have simple object pairs like {name, string} etc bug report - may be available in future functionality... this just means that you need to convert your multi row results into a concatination of results separated by commas and then converted into a json array.

在第二个示例中,您几乎已经掌握了它.

You almost had it with your second example.

您可以通过GROUP_CONCAT函数实现您的目标

You can achieve what you are after with the GROUP_CONCAT function

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;

这几乎可行,最终将子查询视为一个字符串,在其中保留了转义字符.

This almost works, it ends up treating the subquery as a string which leaves the escape characters in there.

'{\"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输出的方式,如下所示:

In order to get this working in an appropriate format, you need to change the way you create the JSON output as follows:

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;

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

This will give you the exact result you require:

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

这篇关于如何使用mysql本地json函数生成嵌套的json对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆