Home > Software engineering >  Add a string column from JSON object array in T-SQL
Add a string column from JSON object array in T-SQL

Time:02-12

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.

CodePudding user response:

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