2

我们正在探索JSON feature in SQL Sever我们想要提出一个可以返回如下 JSON 的 SQL 的场景之一

[
  {
    "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
]

value字段可以是简单的整数/字符串或嵌套对象。

我们可以得出一个如下所示的表格:

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

但是一旦我们申请for json path,它就失败了

由于与另一个列名或别名冲突,无法在 JSON 输出中生成属性“值”。为 SELECT 列表中的每一列使用不同的名称和别名。

有可能以某种方式产生这个吗?该值将在value.uuidvalue不在两者中?

注意:如果我们可以将每一行转换为单独的 JSON 并将它们全部添加到一个数组中,我们愿意接受这种可能性。

4

2 回答 2

2
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;
于 2020-02-26T13:31:43.920 回答
1

此错误的原因是(如文档中所述)... FOR JSON PATH 子句使用列别名或列名来确定 JSON 输出中的键名。如果别名包含点,则 PATH 选项会创建嵌套对象。在您的情况下value.uuidvalue两者都生成一个带有 name 的密钥value

我可以建议一种方法(可能不是最好的方法),它用于JSON_MODIFY()从空 JSON 数组生成预期的 JSON:

桌子:

CREATE TABLE Data (
   [field.uuid] varchar(100),
   [value.uuid] varchar(100), 
   [value] int
)
INSERT INTO Data 
   ([field.uuid], [value.uuid], [value])
VALUES   
   ('uuid-field-1', 'value-uuid', NULL),
   ('uuid-field-2', NULL,         1),
   ('uuid-field-3', NULL,         3),
   ('uuid-field-4', NULL,         4)

陈述:

DECLARE @json nvarchar(max) = N'[]'
SELECT @json = JSON_MODIFY(
   @json, 
   'append $', 
   JSON_QUERY(
      CASE
         WHEN [value.uuid] IS NOT NULL THEN (SELECT d.[field.uuid], [value.uuid] FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)
         WHEN [value] IS NOT NULL THEN (SELECT d.[field.uuid], [value] FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)
      END   
   )   
)   
FROM Data d   
SELECT @json

结果:

[
    {
        "field":{
            "uuid":"uuid-field-1"
        },
        "value":{
            "uuid":"value-uuid"
        }
    },
    {
        "field":{
            "uuid":"uuid-field-2"
        },
        "value":1
    },
    {
        "field":{
            "uuid":"uuid-field-3"
        },
        "value":3
    },
    {
        "field":{
            "uuid":"uuid-field-4"
        },
        "value":4
    }
]
于 2020-02-26T11:53:52.167 回答