发现的怪异 JSON、SQL 服务器和 OPENJSON
Discovery's Weird JSON, SQL Server, and OPENJSON
我正在使用 Discovery 中的 API 从我们的虚拟机中提取一些信息,但是 JSON 由于某些原因在一个节点中有标题而在另一个节点中有值,并且它们是正方形的括号,我很难得到最终结果。
这是 JSON
的 watered-down 版本
DECLARE @JSON nvarchar(max) = N'[
{
"headings": [
"vm_type",
"Hostname"
],
"results": [
[
"AWS EC2 Instance",
null
],
[
"AWS EC2 Instance",
null
]
]
}
]'
SET @JSON = SUBSTRING(@JSON,2,LEN(@JSON) - 2)
SELECT *
FROM OPENJSON(@JSON)
SELECT *
FROM OPENJSON(@JSON,'$.results')
有没有办法将其变成 table,标题作为列名,结果的顺序与其值相同?
你有一个数组数组,所以这实际上是一个动态枢轴。
要进行动态枢轴,您需要动态 SQL。最简单的数据透视方法通常不是使用 PIVOT
,而是使用 MAX(CASE
的条件聚合
DECLARE @sql nvarchar(max) = N'
SELECT
' + (
SELECT STRING_AGG(
QUOTENAME(j.value) + N' = MAX(CASE WHEN j2.[key] = ' + j.[key] + ' THEN j2.value END)',
',
') WITHIN GROUP (ORDER BY j.[key])
FROM OPENJSON(@JSON, '$[0].headings') j
) + '
FROM OPENJSON(@JSON, ''$[0].results'') j1
CROSS APPLY OPENJSON(j1.value) j2
GROUP BY
j1.[key];
';
PRINT @sql; --for testing
EXEC sp_executesql
@sql,
N'@JSON nvarchar(max)',
@JSON = @JSON;
注意正确使用 QUOTENAME
来引用列名,并使用 sp_executesql
和参数来传递实际数据,而不是直接将其注入查询文本。
我正在使用 Discovery 中的 API 从我们的虚拟机中提取一些信息,但是 JSON 由于某些原因在一个节点中有标题而在另一个节点中有值,并且它们是正方形的括号,我很难得到最终结果。
这是 JSON
的 watered-down 版本DECLARE @JSON nvarchar(max) = N'[
{
"headings": [
"vm_type",
"Hostname"
],
"results": [
[
"AWS EC2 Instance",
null
],
[
"AWS EC2 Instance",
null
]
]
}
]'
SET @JSON = SUBSTRING(@JSON,2,LEN(@JSON) - 2)
SELECT *
FROM OPENJSON(@JSON)
SELECT *
FROM OPENJSON(@JSON,'$.results')
有没有办法将其变成 table,标题作为列名,结果的顺序与其值相同?
你有一个数组数组,所以这实际上是一个动态枢轴。
要进行动态枢轴,您需要动态 SQL。最简单的数据透视方法通常不是使用 PIVOT
,而是使用 MAX(CASE
DECLARE @sql nvarchar(max) = N'
SELECT
' + (
SELECT STRING_AGG(
QUOTENAME(j.value) + N' = MAX(CASE WHEN j2.[key] = ' + j.[key] + ' THEN j2.value END)',
',
') WITHIN GROUP (ORDER BY j.[key])
FROM OPENJSON(@JSON, '$[0].headings') j
) + '
FROM OPENJSON(@JSON, ''$[0].results'') j1
CROSS APPLY OPENJSON(j1.value) j2
GROUP BY
j1.[key];
';
PRINT @sql; --for testing
EXEC sp_executesql
@sql,
N'@JSON nvarchar(max)',
@JSON = @JSON;
注意正确使用 QUOTENAME
来引用列名,并使用 sp_executesql
和参数来传递实际数据,而不是直接将其注入查询文本。