sql-server - OPENJSON 扩展了其他列

标签 sql-server json tsql sql-server-2016

我有一个包含类似数据的表

id     deltas
23     [{"prop1": "value1","prop2": "value2},{"prop1": "value3","prop2": "value4}

这里的想法是增量包含一个对象数组。对象的模式总是 prop1 和 prop2 让我们说。这意味着对象将仅包含这 2 个属性。

我所追求的是编写 TSQL 查询,它给我类似的东西:

id   property   value
23   prop1      value1
23   prop2      value2
23   prop1      value3
23   prop2      value4

我已经可以使用 openjson,因为我将兼容级别设置为 130。 我尝试了一个简单的 openjson,但它给我的是一个键值,第一个对象为 0 键,值为 json。我想解析该值的 JSON。

最佳答案

您可以使用 OPENJSON 从 JSON 中提取值,然后使用 UNPIVOT 它们以您想要的格式重新组织值:

--temp table variable that holds your json
declare @source table (id int, props nvarchar(max))
--temp table variable that holds values extracted from your json
declare @tmp table (id int, prop1 nvarchar(max), prop2 nvarchar(max))

--populate temp table with the data you posted
insert into @source
select 23,'[{"prop1": "value1","prop2": "value2"},{"prop1": "value3","prop2": "value4"}]'

--use OPENJSON to extract data from "props" column holding your json
insert into @tmp
select id, prop1,prop2 from  @source  cross apply OPENJSON(props) 
with
(
    prop1 nvarchar(100),
    prop2 nvarchar(100)
)

--unpivot the result to get desired result
select id, u.property, u.value
from  @tmp t
unpivot(
    [value] for [property] in (prop1,prop2)
) u;

这是此 TSQL 片段的输出:

enter image description here

如果您不需要中间结果,您可以避免使用临时表并在一个步骤中处理您的数据:

--temp table variable that holds your json
declare @source table (id int, props nvarchar(max))

--populate temp table with the data you posted
insert into @source
select 23,'[{"prop1": "value1","prop2": "value2"},{"prop1": "value3","prop2": "value4"}]'

--use openjson to fetch data from JSON and then unpivot the result to get desired format
select id, u.property, u.value
from  (select id, prop1, prop2 from  @source  cross apply OPENJSON(props) 
with
(
    prop1 nvarchar(100),
    prop2 nvarchar(100)
)
) t
unpivot(
    [value] for [property] in (t.prop1,t.prop2)
) u;

附言

您发布的 JSON:

[{"prop1": "value1","prop2": "value2},{"prop1": "value3","prop2": "value4}

无效,因为缺少最后一个方括号以及 value2value4 之后的几个引号。您可以使用 ISJSON() 进行检查,它将返回 0:

select isjson(' [{"prop1": "value1","prop2": "value2},{"prop1": "value3","prop2": "value4}')

所以我假设输入实际上是:

[{"prop1": "value1","prop2": "value2"},{"prop1": "value3","prop2": "value4"}]

关于sql-server - OPENJSON 扩展了其他列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43485331/

相关文章:

.net - ADO .Net - 如何在具有多个 IP 地址的系统上的 SqlConnection 中指定源 IP 地址

php - 使用 CURL 获取 JSON 数据

ios - 当 JSON 输入表示 Codable 类型的多个子类时使用 Codable

sql - PIVOT SQL - 指导

sql-server - Django 连接到 SQL Server - django/sql_server - pyodbc

sql-server - 在 SQL Server 中获取查询的列名

sql - 检测 SQL 中的循环引用

mysql - 如何从 node.js 中的 mysql 获取最近添加的重新编码 ID

sql-server - 如何在另一个数据库中创建引用调用者中正确的 sys.objects 表的 UDF 或 View ?

Sql server - 递归删除