how to Convert Table to Json Arrays? how to Convert Table to Json Arrays? json json

how to Convert Table to Json Arrays?


First of all: JSON support needs v2016+. Secondly: The problem here will be the naked array like here "Number": ["1","2","3"]. I have no idea why, but that is not supported at the moment. The rest is rather easy, but this will need some tricks.

Try this

DECLARE @tmp TABLE(    [Color] [nvarchar](50) NULL,    [Type] [nvarchar](50) NULL,    [Number] [nvarchar](50) NULL)INSERT INTO @tmp ([Color], [Type], [Number]) VALUES  (N'Blue', N'A', N'1'),(N'Blue', N'A', N'2'),(N'Blue', N'A', N'3'),(N'Blue', N'B', N'1'),(N'Blue', N'C', N'1'),(N'Red', N'A', N'1'),(N'Red', N'B', N'2');SELECT t.Color     ,(        SELECT t2.[Type]              ,(                SELECT t3.Number                FROM @tmp t3                WHERE t3.Color=t.Color AND t3.[Type]=t2.[Type]                FOR JSON PATH               ) AS Number        FROM @tmp t2        WHERE t2.Color=t.Color        GROUP BY t2.[Type]        FOR JSON PATH      ) AS PartFROM @tmp tGROUP BY t.ColorFOR JSON PATH;

the result (formatted)

[    {        "Color": "Blue",        "Part": [            {                "Type": "A",                "Number": [                    {                        "Number": "1"                    },                    {                        "Number": "2"                    },                    {                        "Number": "3"                    }                ]            },            {                "Type": "B",                "Number": [                    {                        "Number": "1"                    }                ]            },            {                "Type": "C",                "Number": [                    {                        "Number": "1"                    }                ]            }        ]    },    {        "Color": "Red",        "Part": [            {                "Type": "A",                "Number": [                    {                        "Number": "1"                    }                ]            },            {                "Type": "B",                "Number": [                    {                        "Number": "2"                    }                ]            }        ]    }]

Now we have to use rather ugly tricks with REPLACE to get rid of the array of objects in the middle:

SELECT REPLACE(REPLACE(REPLACE((    SELECT t.Color         ,(            SELECT t2.[Type]                  ,(                    SELECT t3.Number                    FROM @tmp t3                    WHERE t3.Color=t.Color AND t3.[Type]=t2.[Type]                    FOR JSON PATH                   ) AS Number            FROM @tmp t2            WHERE t2.Color=t.Color            GROUP BY t2.[Type]            FOR JSON PATH          ) AS Part    FROM @tmp t    GROUP BY t.Color    FOR JSON PATH),'},{"Number":',','),'{"Number":',''),'}]}',']}');

the result

[    {        "Color": "Blue",        "Part": [            {                "Type": "A",                "Number": [                    "1",                    "2",                    "3"                ]            },            {                "Type": "B",                "Number": [                    "1"                ]            },            {                "Type": "C",                "Number": [                    "1"                ]            }        ]    },    {        "Color": "Red",        "Part": [            {                "Type": "A",                "Number": [                    "1"                ]            },            {                "Type": "B",                "Number": [                    "2"                ]            }        ]    }]

UPDATE

It might be a bit easier and cleaner to create the naked array on string level:

SELECT t.Color        ,(        SELECT t2.[Type]                ,JSON_QUERY('[' + STUFF((                SELECT CONCAT(',"',t3.Number,'"')                FROM @tmp t3                WHERE t3.Color=t.Color AND t3.[Type]=t2.[Type]                FOR XML PATH('')),1,1,'') + ']') AS Number        FROM @tmp t2        WHERE t2.Color=t.Color        GROUP BY t2.[Type]        FOR JSON PATH        ) AS PartFROM @tmp tGROUP BY t.ColorFOR JSON PATH;

UPDATE 2: Starting with v2017 there is STRING_AGG()

You can try this on v2017

SELECT t.Color        ,(        SELECT t2.[Type]                ,JSON_QUERY('["' + STRING_AGG(t2.Number,'","') + '"]') AS Number        FROM @tmp t2        WHERE t2.Color=t.Color        GROUP BY t2.[Type]        FOR JSON PATH        ) AS PartFROM @tmp tGROUP BY t.ColorFOR JSON PATH;