使用TSQL OPENJSON如何从JSON数组中提取具有动态键名的值

使用TSQL OPENJSON如何从JSON数组中提取具有动态键名的值,tsql,azure-sql-database,open-json,Tsql,Azure Sql Database,Open Json,我有一个带有内部属性数组的json文档。在其中一个属性上,密钥名称会动态/随机更改。我可以很容易地提取除最后一个讨厌的属性之外的所有数据点。我以前在OPENJSON中发现或使用的所有方法都依赖于已知的键名 在“内部”数组中,第一个属性的键名将发生更改。我想提取与该动态键关联的值,而不知道该键将是什么。希望下面的代码能比我用文字更好地描述这个问题 以下是JSON文档的格式,以便于阅读 { "outer1": { "inner1": { "dynami

我有一个带有内部属性数组的json文档。在其中一个属性上,密钥名称会动态/随机更改。我可以很容易地提取除最后一个讨厌的属性之外的所有数据点。我以前在OPENJSON中发现或使用的所有方法都依赖于已知的键名

在“内部”数组中,第一个属性的键名将发生更改。我想提取与该动态键关联的值,而不知道该键将是什么。希望下面的代码能比我用文字更好地描述这个问题

以下是JSON文档的格式,以便于阅读

{
    "outer1": {
        "inner1": {
            "dynamicKey123": "attribute1",
            "staticKey1": "attribute2",
            "staticKey2": "attribute3",
            "staticKey3": "attribute4"
        }
    },
    "outer2": {
        "inner2": {
            "dynamicKeyABC": "attribute1",
            "staticKey1": "attribute2",
            "staticKey2": "attribute3",
            "staticKey3": "attribute4"
        }
    }
}
一些要测试的代码

创建表openjson_test(json_col VARCHAR(MAX));
插入openjson_测试(json_列)
值({“outer1”:{“inner1”:{“dynamicKey123”:“attribute1”,“staticKey1”:“attribute2”,“staticKey2”:“attribute3”,“staticKey3”:“attribute4”},,“outer2”:{“inner2”:“dynamicKeyABC”:“attribute1”,“staticKey1”:“attribute2”,“staticKey2”:“attribute3”,“staticKey3”:“attribute4”}});
到目前为止,我开发的查询中有一些麻烦的部分被注释掉了

选择
朱若谷,
所以作为soKey,
是的,作为西基,
si.[value]作为siValue,
--阿尔·戴米奇,
ar.1,
ar.2,
ar.3
从openjson_测试
交叉应用OPENJSON(json_col)so
交叉应用OPENJSON(json_col,'$.+so.[key])si
交叉应用OPENJSON(json_col,'$.+so.[key]+'.+si.[key])
与(
--dynamicKey VARCHAR(256)$.dynamicKey???,如何在不知道键的情况下提取此值
staticKey1 VARCHAR(256)'$.staticKey1',
staticKey2 VARCHAR(256)'$.staticKey2',
staticKey3 VARCHAR(256)“$.staticKey3”
)ar

您可以在不使用
WITH
子句的情况下使用
OPENJSON
,并过滤掉具有已知名称的列:

SELECT json_col,
    so.[key] AS soKey,
    si.[key] AS siKey,
    si.[value] AS siValue,
    ar2.Value AS dynamicKey,
    ar.staticKey1,
    ar.staticKey2,
    ar.staticKey3
FROM dbo.openjson_test t
CROSS APPLY OPENJSON(t.json_col) so
CROSS APPLY OPENJSON(json_col, '$.' + so.[key]) si
CROSS APPLY OPENJSON(json_col, '$.' + so.[key] + '.' + si.[key])
WITH (
    staticKey1 VARCHAR(256) '$.staticKey1',
    staticKey2 VARCHAR(256) '$.staticKey2',
    staticKey3 VARCHAR(256) '$.staticKey3'
) ar
CROSS APPLY (
    SELECT *
    FROM OPENJSON(json_col, '$.' + so.[key] + '.' + si.[key])
    WHERE [Key] NOT IN ('staticKey1','staticKey2','staticKey3')
) ar2

我建议使用条件聚合的方法


此技术用于
PIVOT
场景,但允许更通用的逻辑。

谢谢@RazvanSocol@K_OFLYNN:请对你认为有用的答案进行投票(见)。谢谢,欢迎来到StackOverflow!谢谢@Shnugo。非常干净的溶液
SELECT
    so.[key] AS soKey,
    si.[key] AS siKey,
    MAX(CASE WHEN attr.[key] NOT IN('staticKey1','staticKey2','staticKey3') THEN attr.[value] END) AS DynamicAttr,
    MAX(CASE WHEN attr.[key]='staticKey1' THEN attr.[value] END) AS attrKey1,
    MAX(CASE WHEN attr.[key]='staticKey2' THEN attr.[value] END) AS attrKey2,
    MAX(CASE WHEN attr.[key]='staticKey3' THEN attr.[value] END) AS attrKey3
FROM openjson_test
CROSS APPLY OPENJSON(json_col) so
CROSS APPLY OPENJSON(json_col, '$.' + so.[key]) si
CROSS APPLY OPENJSON(json_col, '$.' + so.[key] + '.' + si.[key]) attr
GROUP BY so.[key],si.[key];