SQL到JSON父/子关系

时间:2018-12-13 17:24:45

标签: sql json sql-server tsql sql-server-2017

我的Microsoft SQL Server 2017中有一个看起来像这样的表:

+----+-------+----------+-------+-----------+
| ID | Level | ParentID | IsEnd | SomeText  |
+----+-------+----------+-------+-----------+
|  1 |     1 |    null  |     1 |   abc     |
|  2 |     1 |    null  |     1 |   asd     |
|  3 |     2 |    1     |     1 |   weqweq  |
|  4 |     2 |    1     |     0 |   lkjlkje |
|  5 |     3 |    4     |     1 |   noonwqe |
|  6 |     3 |    4     |     0 |   wet4t4  |
+----+-------+----------+-------+-----------+

我想输出一个json字符串:

[{  ID: 1,
SomeText: 'abc',
Child2: [{
        ID: 3,
        SomeText: 'weqweq'
    }, {
        ID: 4,
        SomeText: 'lkjlkje',
        Child3: [{
                ID: 5,
                SomeText: 'noonwqe'
            }, {
                ID: 6,
                SomeText: 'wet4t4'
            }
        ]}
        ] 
}]

IsEnd是一个标志,用于了解您到达最后一级的位置。

1 个答案:

答案 0 :(得分:0)

您可以使用从根开始构建层次结构的递归标量UDF(用户定义函数)。

这是您可以从以下位置开始的UDF的存根:

create function dbo.udf_create_json_tree(@currentId int) 
    returns varchar(max)
begin 
    declare @json nvarchar(max) 
    declare @id int, @parentId int, @someText varchar(50)

    select @id =[ID], @parentId = ParentID, @someText = SomeText
    from dbo.tmp 
    where [ID] = @currentId

    set @json =  
        (
            select [ID], SomeText, json_query(dbo.udf_create_json_tree([ID])) as Child 
            from dbo.tmp   
            where ParentID = @currentId 
            for json auto
        );

    if(@parentId is null) 
       set @json = concat(
                          '[{"ID":' + cast (@id as nvarchar(50)) ,
                          ',"SomeText":"' , @someText , 
                          '","Child":' , cast(@json as nvarchar(max)) ,
                          '}]'
                          )
    return @json  
end 

使用输入值填充表:

create table tmp ([ID] int, [Level] int, ParentID int, IsEnd bit, SomeText varchar(50))
insert into tmp values
 (1, 1, null,1, 'abc'    )
,(2, 1, null,1, 'asd'    )
,(3, 2, 1   ,1, 'weqweq' )
,(4, 2, 1   ,0, 'lkjlkje')
,(5, 3, 4   ,1, 'noonwqe')
,(6, 3, 4   ,0, 'wet4t4' )

现在您可以在第一个节点(ID = 1)上调用UDF:

select dbo.udf_create_json_tree(1)

Json结果:

enter image description here

格式化的json结果:

[{
    "ID": 1,
    "SomeText": "abc",
    "Child": [{
        "ID": 3,
        "SomeText": "weqweq"
    },
    {
        "ID": 4,
        "SomeText": "lkjlkje",
        "Child": [{
            "ID": 5,
            "SomeText": "noonwqe"
        },
        {
            "ID": 6,
            "SomeText": "wet4t4"
        }]
    }]
}]

如果您确实需要使用级别编号(Child2,Childx等)来命名每个子节点,则可能需要对“ Child”字符串实施替换逻辑。