Add a string column from JSON object array in T-SQL

Viewed 53

I want to create a single string from specific values in a nested JSON array and add the resulting string as a column. I have code similar to this:

DECLARE @json NVARCHAR(MAX) = N'[  
  {
      "id": 2,
      "info": {
          "name": "John",
          "surname": "Smith",
          "age": 25
        }
    },
    {
        "id": 5,
        "info": {
            "name": "Jane",
            "surname": "Smith",
            "skills": [
                {
                    "name": "SQL",
                    "group": "SQLnerds"
                },
                {
                    "name": "C#",
                    "group": "C#nerds"
                },
                {
                    "name": "Azure",
                    "group": "Azurenerds"
                }
            ]
        },
        "dob": "2005-11-04T12:00:00"
    }  
]';

SELECT id,
firstName,
lastName,
age,
dateOfBirth,
JSON_VALUE(skills, '$[0].name') as singleskill,
skills,
STRING_AGG(CONVERT(nvarchar(max), JSON_VALUE(skills, '$.name')), ',') as skillstring
FROM OPENJSON(@json)  
  WITH (
    id INT '$.id',
    firstName NVARCHAR(50) '$.info.name',
    lastName NVARCHAR(50) '$.info.surname',  
    age INT '$.info.age',
    dateOfBirth DATETIME2 '$.dob',
    skills NVARCHAR(MAX) '$.info.skills' AS JSON
  ) 
GROUP BY  id, firstName, lastName, age, dateOfBirth, skills

enter image description here

The result I want is 2 lines with a skills column containing the json and a skillstring column containing a aggregated string with skill names like 'SQL,C#,Azure' and NULL if no skills are present.

I'm pretty sure the STRING_AGG can do this for me, but I cannot figure out how to get the values out of the JSON string.

1 Answers

You can try to use OUTER APPLY with another OPENJSON by skills column, then you will get the skill name from JSON array per id.

final you might use STRING_AGG function to get your expect result

SELECT v.id,
      v.firstName,
      v.lastName,
      v.age,
      v.dateOfBirth,
      JSON_VALUE(v.skills, '$[0].name') as singleskill,
      v.skills,
      STRING_AGG( v2.skill_name, ',') as skillstring
FROM OPENJSON(@json)  
  WITH (
    id INT '$.id',
    firstName NVARCHAR(50) '$.info.name',
    lastName NVARCHAR(50) '$.info.surname',  
    age INT '$.info.age',
    dateOfBirth DATETIME2 '$.dob',
    skills NVARCHAR(MAX) '$.info.skills' AS JSON
) as v 
OUTER APPLY OPENJSON(skills) WITH (
   skill_name NVARCHAR(100) '$.name' 
) as v2
GROUP BY  v.id, v.firstName, v.lastName, v.age, v.dateOfBirth, v.skills

;

sqlfiddle

Related