我有一个表,其中包含带有组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"}}]
答案 0 :(得分:2)
如果我对您的理解正确,那么下一种方法可能会有所帮助。只需使用json
和OPENJSON()
子句选择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"}
]
}
]