How to generate hierarchical JSON data with Microsoft SQL Server 2016?

后端 未结 2 638
难免孤独
难免孤独 2021-01-04 21:20

I\'m using Microsoft SQL Server 2016. This version supports JSON.

I have a Person table with the following data:

Pe         


        
2条回答
  •  猫巷女王i
    2021-01-04 22:03

    Unfortunately, recursive CTe cannot be used to generate hierarchical json . Output of recursive CTE is still flat result.

    The only way to create hierarchical output is to create separate CTE for each level and then join the using FOR JSON AUTO

    Prepare table:

    declare @t table (PersonId int, FatherId int, Name nvarchar(20));
    
    insert into @t(PersonId, FatherId, Name)
    values
    (1, NULL, '4th Grand Father'),
    (2, 1, '3rd Grand Father'),
    (3, 2, '2nd Grand Father'),
    (4, 3, 'Grand Father'),
    (5, 4, 'Father'),
    (6, 4, 'Uncle'),
    (7, 6, 'Cousin'),
    (8, 5, 'Brother'),
    (9, 5, 'Me');
    

    -- Hierarchical query:

    WITH
    Persons_CTE1 AS(
        SELECT PersonId, FatherId, Name FROM @t WHERE FatherId IS NULL
    ),
    Persons_CTE2 AS(
        SELECT P.PersonId, P.FatherId, P.Name
        from @t P
        WHERE P.FatherId IN (SELECT PersonId FROM Persons_CTE1)
    ),
    Persons_CTE3 AS(
        SELECT P.PersonId, P.FatherId, P.Name
        from @t P
        WHERE P.FatherId IN (SELECT PersonId FROM Persons_CTE2)
    ),
    Persons_CTE4 AS(
        SELECT P.PersonId, P.FatherId, P.Name
        from @t P
        WHERE P.FatherId IN (SELECT PersonId FROM Persons_CTE3)
    ),
    Persons_CTE5 AS(
        SELECT P.PersonId, P.FatherId, P.Name
        from @t P
        WHERE P.FatherId IN (SELECT PersonId FROM Persons_CTE4)
    ),
    Persons_CTE6 AS(
        SELECT P.PersonId, P.FatherId, P.Name
        from @t P
        WHERE P.FatherId IN (SELECT PersonId FROM Persons_CTE5)
    )
    select Persons_CTE1.Name, Persons_CTE2.Name, Persons_CTE3.Name,
           Persons_CTE4.Name, Persons_CTE5.Name, Persons_CTE6.Name
    from Persons_CTE1
        LEFT JOIN Persons_CTE2
            ON Persons_CTE2.FatherId = Persons_CTE1.PersonId
        LEFT JOIN Persons_CTE3
            ON Persons_CTE3.FatherId = Persons_CTE2.PersonId
        LEFT JOIN Persons_CTE4
            ON Persons_CTE4.FatherId = Persons_CTE3.PersonId
        LEFT JOIN Persons_CTE5
            ON Persons_CTE5.FatherId = Persons_CTE4.PersonId
        LEFT JOIN Persons_CTE6
            ON Persons_CTE6.FatherId = Persons_CTE5.PersonId
    FOR JSON AUTO
    

提交回复
热议问题