我需要从JSON格式获取数组中的最后一项。我有这个JSON。
@json =
N'{
"solution": "xxxxxxxxxxxxxxxxxxxxx",
"options": [
{
"choice_id": 205073,
"choice": "aaaa"
},
{
"choice_id": 205074,
"choice": "bbbb"
},
{
"choice_id": 205075,
"choice": "cccc"
},
{
"choice_id": 205076,
"choice": "dddd"
}
],
}'
我想得到
@json =
N'{
"solution": "xxxxxxxxxxxxxxxxxxxxx",
"options": {
"choice_id": 205076,
"choice": "dddd"
}
}
我如何获得那个结果?
答案 0 :(得分:3)
您可以使用OPENJSON切碎并重新组装FOR JSON文档(请参阅@ digital.aaron的答案),也可以使用JSON_MODIFY,如下所示:
declare @json nvarchar(max) =
N'{
"solution": "xxxxxxxxxxxxxxxxxxxxx",
"options": [
{
"choice_id": 205073,
"choice": "aaaa"
},
{
"choice_id": 205074,
"choice": "bbbb"
},
{
"choice_id": 205075,
"choice": "cccc"
},
{
"choice_id": 205076,
"choice": "dddd"
}
]
}'
declare @options nvarchar(max) = (
select top 1 value
from openjson(@json,'$.options')
order by [key] desc
);
set @json = json_modify(@json, '$.options', json_query(@options))
select @json
输出
{
"solution": "xxxxxxxxxxxxxxxxxxxxx",
"options": {
"choice_id": 205076,
"choice": "dddd"
}
}
请注意,JSON_QUERY函数还用于将字符串解析为JSON片段。否则,@ options中的值将作为单个字符串值而不是json对象插入。
答案 1 :(得分:3)
您可以尝试
DECLARE @json NVARCHAR(MAX) =
N'{
"solution": "xxxxxxxxxxxxxxxxxxxxx",
"options": [
{
"choice_id": 205073,
"choice": "aaaa"
},
{
"choice_id": 205074,
"choice": "bbbb"
},
{
"choice_id": 205075,
"choice": "cccc"
},
{
"choice_id": 205076,
"choice": "dddd"
}
]
}';
SELECT TOP 1
A.solution
,JSON_QUERY(B.[value]) AS options
FROM OPENJSON(@json) WITH (solution nvarchar(max), options NVARCHAR(MAX) AS JSON) A
CROSS APPLY OPENJSON(A.options) B
ORDER BY B.[key] DESC
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER;
结果
{"solution":"xxxxxxxxxxxxxxxxxxxxx"
,"options":{
"choice_id": 205076,
"choice": "dddd"
}
}
FROM OPENJSON
将深入您的JSON并找到顶级元素。我们按原样获取solution
,并声明AS JSON
以供options
指定,此值稍后将被视为JSON。
CROSS APPLY
将再次调用OPENJSON
,但是这次针对options
,我们将得到一个数组。 key
列是数组中的顺序位置,因此我们可以使用TOP 1
和ORDER BY key DESC
来获取数组中的最后一个元素。
在将查询重新组合为JSON之前,我们必须用B.value
包装JSON_QUERY()
。否则,我们会在JSON中看到转义字符,例如\t
或\r\n
。原因:如果没有此字符串,则JSON字符串将不会被当作JSON字符串,而会被当作任何其他字符串,并会作为一个单独的文本值打包到结果中。
答案 2 :(得分:2)
首先,您的JSON字符串格式错误。您需要在右方括号后面删除逗号。
所以我们声明一下变量:
DECLARE @json NVARCHAR(MAX) = N'{
"solution": "xxxxxxxxxxxxxxxxxxxxx",
"options": [
{
"choice_id": 205073,
"choice": "aaaa"
},
{
"choice_id": 205074,
"choice": "bbbb"
},
{
"choice_id": 205075,
"choice": "cccc"
},
{
"choice_id": 205076,
"choice": "dddd"
}
]
}'
现在,您可以结合使用OPENJSON()
和FOR JSON
来获取数组中的最后一条记录。
SELECT jsonfield = CAST((
SELECT TOP 1
j.solution
,o.choice_id
,o.choice
FROM
OPENJSON(@json)
WITH
(
solution VARCHAR(MAX) '$.solution'
,options NVARCHAR(MAX) '$.options' AS JSON
) j
CROSS APPLY
OPENJSON(options)
WITH
(
choice_id INT '$.choice_id'
,choice VARCHAR(4) '$.choice'
) o
ORDER BY o.choice_id DESC
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) AS NVARCHAR(MAX))
编辑:
或者,如果您不想按任何节点值进行排序,也可以使用此查询:
SELECT jsonfield = CAST((
SELECT TOP 1
j.solution
--,o.*
,c.choice_id
,c.choice
FROM OPENJSON(@json)
WITH
(
solution VARCHAR(MAX) '$.solution'
,options NVARCHAR(MAX) '$.options' AS JSON
) j
CROSS APPLY OPENJSON(options) o
CROSS APPLY OPENJSON(o.Value)
WITH (
choice_id int '$.choice_id',
choice varchar(4) '$.choice'
) c
ORDER BY [key] DESC
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) AS NVARCHAR(MAX))