使用列值作为 JSON 属性名称从 SQL Server 表创建 JSON

RMD*_*RMD 6 t-sql sql-server json azure-sql-database

我在 SQL Azure DB(2019 兼容级别)中有一个具有以下架构的表:

CREATE TABLE dbo.Properties
(
    PropertyId int, 
    PropertyName nvarchar(100),
    PropertyValue nvarchar(1000)
)
Run Code Online (Sandbox Code Playgroud)

我想获取此表中的数据,并将其转换为 JSON,使用 PropertyName 列中的值作为 JSON 属性的名称,显然使用 PropertyValue 值作为 JSON 属性值。

编辑 12/10/2021: 重要的是,PropertyName 列中的值无法提前预测。

例如,考虑表中的数据(3 行):

1, "Color", "Blue"
1, "Name", "John"
1, "Cost", 5
Run Code Online (Sandbox Code Playgroud)

上面的内容将转换为以下 JSON:

{"Color":"Blue", "Name":"John", "Cost":5}
Run Code Online (Sandbox Code Playgroud)

显然我可以使用 STRING_AGG 函数来做到这一点,如下所示:

SELECT '{' + STRING_AGG( '"' + p.PropertyName + '": ''' + p.PropertyValue,''',')  
WITHIN GROUP (ORDER BY p.PropertyName) + '}' AS MyJson
FROM dbo.Properties p
GROUP BY p.Id
Run Code Online (Sandbox Code Playgroud)

但我希望使用 JSON 函数中的一个构建,而不是拼凑一个大字符串。

wBo*_*Bob 3

FOR JSON AUTO从列名称开始工作,因此获得所需结果的一种方法是将属性名称透视到列中。例如:

SELECT Color, [Name], Cost 
FROM dbo.Properties
PIVOT ( MAX( PropertyValue ) For PropertyName In ( [Color], [Name], Cost ) ) pvt
FOR JSON AUTO;
Run Code Online (Sandbox Code Playgroud)

我的结果:

结果

当然,只有当您的 JSON 属性/列名称始终已知并且这是一个简单的示例时,这才方便。对于更复杂的示例,您可能正在查看动态数据透视或动态 SQL,并且您的STRING_AGG示例还不错。