Search code examples
jsonsql-serverdatabasesql-server-json

SQL Server For JSON Path dynamic column name


We are exploring the JSON feature in SQL Sever and for one of the scenarios we want to come up with a SQL which can return a JSON like below

[
  {
    "field": {
      "uuid": "uuid-field-1"
    },
    "value": {
      "uuid": "uuid-value" //value is an object
    }
  },
  {
    "field": {
      "uuid": "uuid-field-2"
    },
    "value": "1". //value is simple integer
  }
  ... more rows
]

The value field can be a simple integer/string or a nested object.

We are able to come up with a table which looks like below:

field.uuid  | value.uuid | value|
------------|----------  | -----|
uuid-field-1| value-uuid | null |
uuid-field-2| null       | 1    |
  ... more rows

But as soon as we apply for json path, it fails saying

Property 'value' cannot be generated in JSON output due to a conflict with another column name or alias. Use different names and aliases for each column in SELECT list.

Is it possible to do it somehow generate this? The value will either be in the value.uuid or value not both?

Note: We are open to possibility of if we can convert each row to individual JSON and add all of them in an array.


Solution

  • select
        json_query((select v.[field.uuid] as 'uuid' for json path, without_array_wrapper)) as 'field',
        value as 'value',
        json_query((select v.[value.uuid] as 'uuid' where v.[value.uuid] is not null for json path, without_array_wrapper)) as 'value'
    from
    (
    values 
        ('uuid-field-1', 'value-uuid1', null),
        ('uuid-field-2', null,  2),
        ('uuid-field-3', 'value-uuid3', null),
        ('uuid-field-4', null,  4)
    ) as v([field.uuid], [value.uuid], value)
    for json auto;--, without_array_wrapper;