我可以在不使源列名称成为SQL Server 2016中键的情况下使用FOR JSON吗?

时间:2019-04-18 09:19:51

标签: sql json sql-server tsql

我有一个表,其中包含带有组ID的json字符串。我想创建一个包含所有具有相同ID的json对象的json数组。

请注意,就我而言,我要放入数组中的列内容本身就是json代码段,因此,我的案例和问题比将行变成数组更具体。在接受的答案中使用OPENJSON也可以利用此细节。

但是,我找不到使用FOR JSON的方法,该方法允许我选择一个列,而该列的名称不会成为数组中所有对象的键。

我意识到我想摆脱的键对于将列投影到json的键值表示的键是必要的,但是在这种情况下,我仅选择一列,并且我很好奇是否存在我想不到的把戏。

我可以通过简单地使用COALASCE来实现我想要的,但是我想知道是否可以使用FOR JSON处理这种边缘情况。这是简化的代码,演示了我正在尝试做的事情:

BEGIN
    declare @Json_Snippets table (id int, json nvarchar(max));

    insert into @Json_Snippets (id, json) VALUES (1, '{"root":{"obj":"one"}}');
    insert into @Json_Snippets (id, json) VALUES (1, '{"root":{"obj":"two"}}');

   select
          JSON_QUERY(js.json) as 'dont_want_this'
   from
        @Json_Snippets js
    FOR JSON PATH;

END

我必须使用JSON_QUERY以避免在json列中转义字符,即json字符串保持为json。运行上面的命令可以得到:

[{"dont_want_this":{"root":{"obj":"one"}}},{"dont_want_this":{"root":{"obj":"two"}}}]

我想要得到的是:

[{"root":{"obj":"one"}},{"root":{"obj":"two"}}]

3 个答案:

答案 0 :(得分:2)

如果我对您的理解正确,那么下一种方法可能会有所帮助。只需使用jsonOPENJSON()子句选择WITH数据,然后使用FOR JSON格式化结果:

-- Table
declare @Json_Snippets table (id int, json nvarchar(max));
insert into @Json_Snippets (id, json) VALUES (1, '{"root":{"obj":"one"}}');
insert into @Json_Snippets (id, json) VALUES (1, '{"root":{"obj":"two"}}');

-- Statement
SELECT j.[root]
FROM @Json_Snippets t
CROSS APPLY OPENJSON(t.json, '$') WITH ([root] nvarchar(max) AS JSON) j
FOR JSON AUTO

输出:

[{"root":{"obj":"one"}},{"root":{"obj":"two"}}]

答案 1 :(得分:1)

如果您知道根密钥,则可以使用OPENJSON() WITH (... AS JSON)将其值提取为json,然后使用FOR JSON重新创建json。这是一个示例:

DECLARE @json_snippets TABLE (id INT, json NVARCHAR(MAX));
INSERT INTO @json_snippets (id, json) VALUES
(1, '{"root":{"obj":"one"}}'),
(1, '{"root":{"obj":"two","foo":"bar"}}'),
(2, '{"root":{"obj":"three"}}');

SELECT id, (
    SELECT j.*
    FROM @json_snippets AS x
    CROSS APPLY OPENJSON(json) WITH (
        root NVARCHAR(MAX) AS JSON
    ) AS j
    WHERE id = t.id
    FOR JSON AUTO
)
FROM @json_snippets AS t
GROUP BY id

答案 2 :(得分:0)

DECLARE @json_snippets TABLE (person INT, [json] NVARCHAR(MAX));
INSERT INTO @json_snippets (person, json) VALUES
(1, '{"obj":"one"}'),
(1, '{"obj":"two","foo":"bar"}'),
(2, '{"obj":"three"}');

SELECT x.person, JSON_QUERY('[' +x.sagg + ']') as objs
FROM (
    SELECT  w.person, STRING_AGG ([json], ',') as sagg
    FROM @json_snippets as w
    GROUP BY w.person
) as x
FOR JSON PATH

结果(我尽最大努力进行漂亮的打印):

[
    {"person":1,"objs":[
                 {"obj":"one"}
                 ,{"obj":"two","foo":"bar"}
            ]
    }
    ,{"person":2,"objs":[
                {"obj":"three"}
            ]
    }
]