如何通过CROSS APPLY获取多层嵌套JSON属性的值?

huangapple go评论59阅读模式
英文:

How to get a multi-level Nested JSON property's value via CROSS APPLY?

问题

以下是翻译好的部分:

{
    "id": "f53283cc-5af7-4864-a3f6-86f69d81ae93",
    "SectionId": 5493,
    "Fields": [
        {
            "FieldId": 17943,
            "FieldValue": "[{\"Web_Id\":\"1;#99999984_6_11_018111\",\"EDF\":[{\"key\":\"Orders\",\"val\":\"1\"}],\"CCID\":\"1;#AVSPN004987\",\"G\":null}]",
            "FieldName": "<p>Primary_Product</p>17943",
            "VersionID": 2
        }
    ]
}

请注意,我已将HTML实体编码解码为正常的JSON文本。如果您需要进一步的帮助,请告诉我。

英文:

We have JSON data in this format:

{
    &quot;id&quot;: &quot;f53283cc-5af7-4864-a3f6-86f69d81ae93&quot;,
    &quot;SectionId&quot;: 5493,
    &quot;Fields&quot;: [
        {
            &quot;FieldId&quot;: 17943,
            &quot;FieldValue&quot;: 
                &quot;[
                    {
                        \&quot;Web_Id\&quot;:\&quot;1;#99999984_6_11_018111\&quot;,
                        \&quot;EDF\&quot;:
                            [
                                {
                                    \&quot;key\&quot;:\&quot;Orders\&quot;,
                                    \&quot;val\&quot;:\&quot;1\&quot;
                                }
                            ],
                        \&quot;CCID\&quot;:\&quot;1;#AVSPN004987\&quot;,
                        \&quot;G\&quot;:null
                    }
                ]&quot;,
            &quot;FieldName&quot;: &quot;&lt;p&gt;Primary_Product&lt;/p&gt;17943&quot;,
            &quot;VersionID&quot;: 2
        }
    ]
}

From this data, I can pull values from the Fields property level like the FieldID, FieldValue, FieldName and VersionID using the query below. However, I would like to know if it's possible to pull the WebId or the CCID from the FieldValue element? Currently, I'm doing a SUBSTRING to get the value:

SELECT
  AC_ID
  , FieldID
  , CASE
    WHEN FieldName LIKE &#39;%Item_Description%&#39; THEN &#39;Item Description&#39;
    WHEN FieldName LIKE &#39;%Item_Number%&#39; THEN &#39;Item Number&#39;
    WHEN FieldName LIKE &#39;%Primary_Product%&#39; THEN &#39;Primary Product&#39;
    ELSE &#39;&#39;
    END AS Field
  , CASE
    WHEN FieldID &lt;&gt; &#39;17943&#39; THEN FieldValue
    WHEN FieldID = &#39;17943&#39; THEN SUBSTRING(STUFF(FieldValue, 1, 15, &#39;&#39;), 1, CHARINDEX(&#39;&quot;&#39;, STUFF(FieldValue, 1, 15, &#39;&#39;)) - 1)
    ELSE NULL
    END AS FieldValue
  , SUBSTRING(STUFF(FieldValue, 1, 15, &#39;&#39;), 1, CHARINDEX(&#39;&quot;&#39;, STUFF(FieldValue, 1, 15, &#39;&#39;)) - 1)

FROM CTE_BASE
CROSS APPLY OPENJSON(CTE_BASE.Fields)
WITH (
  FieldId VARCHAR(10) &#39;$.FieldId&#39;
  , FieldName VARCHAR(MAX) &#39;$.FieldName&#39;
  , FieldValue VARCHAR(MAX) &#39;$.FieldValue&#39;
) AS CDB

答案1

得分: 4

以下是您要翻译的内容:

"$.FieldValue" 部分的 JSON 似乎是存储为字符串的 JSON 数组。但我认为使用一个额外的 "APPLY" 运算符将返回期望的结果。

简化的测试数据:

DECLARE @json nvarchar(max) = N'{
   "id":"f53283cc-5af7-4864-a3f6-86f69d81ae93",
   "SectionId":5493,
   "Fields":[
      {
         "FieldId":17943,
         "FieldValue":"[{"Web_Id":"1;#99999984_6_11_018111","EDF":[{"key":"Orders","val":"1"}],"CCID":"1;#AVSPN004987","G":null}]",
         "FieldName":"<p>Primary_Product</p>17943",
         "VersionID":2
      }
   ]
}';

语句:

SELECT *
FROM OPENJSON(@json, '$.Fields') WITH (
  FieldId VARCHAR(10) '$.FieldId', 
  FieldName VARCHAR(MAX) '$.FieldName', 
  FieldValue NVARCHAR(MAX) '$.FieldValue'
) j1
CROSS APPLY OPENJSON(j1.FieldValue) WITH (
  Web_Id varchar(50) '$.Web_Id',
  CCID varchar(50) '$.CCID'
) j2
FieldId FieldName FieldValue Web_Id CCID
17943

Primary_Product

17943

[{"Web_Id":"1;#99999984_6_11_018111","EDF":[{"key":"Orders","val":"1"}],"CCID":"1;#AVSPN004987","G":null}] 1;#99999984_6_11_018111 1;#AVSPN004987

请注意,如果存储的 JSON 中的 "Field.Value" 部分存储为 JSON 数组,而不是字符串,您将需要使用 "AS JSON" 修饰符来获取嵌套的 JSON 内容。

作为文本的 JSON 数组:

DECLARE @json1 nvarchar(max) = N'{
   "Fields":[
      {"FieldValue":"[{"key":"value"}]"}
   ]
}';
SELECT *
FROM OPENJSON(@json1, '$.Fields') WITH (
  FieldValue NVARCHAR(MAX) '$.FieldValue'
) j1
CROSS APPLY OPENJSON(j1.FieldValue) WITH (
  [key] varchar(50) '$.key'
) j2

作为 JSON 的 JSON 数组:

DECLARE @json2 nvarchar(max) = N'{
   "Fields":[
      {"FieldValue":[{"key":"value"}]}
   ]
}';
SELECT *
FROM OPENJSON(@json2, '$.Fields') WITH (
  FieldValue NVARCHAR(MAX) '$.FieldValue' AS JSON
) j1
CROSS APPLY OPENJSON(j1.FieldValue) WITH (
  [key] varchar(50) '$.key'
) j2
FieldValue key
[{"key":"value"}] value
英文:

It seems that the $.FieldValue part of the JSON is a JSON array stored as a string. But I think that one addiitonal APPLY operator will return the expected results.

Simplified test data:

DECLARE @json nvarchar(max) = N&#39;{
   &quot;id&quot;:&quot;f53283cc-5af7-4864-a3f6-86f69d81ae93&quot;,
   &quot;SectionId&quot;:5493,
   &quot;Fields&quot;:[
      {
         &quot;FieldId&quot;:17943,
         &quot;FieldValue&quot;:&quot;[{\&quot;Web_Id\&quot;:\&quot;1;#99999984_6_11_018111\&quot;,\&quot;EDF\&quot;:[{\&quot;key\&quot;:\&quot;Orders\&quot;,\&quot;val\&quot;:\&quot;1\&quot;}],\&quot;CCID\&quot;:\&quot;1;#AVSPN004987\&quot;,\&quot;G\&quot;:null}]&quot;,
         &quot;FieldName&quot;:&quot;&lt;p&gt;Primary_Product&lt;/p&gt;17943&quot;,
         &quot;VersionID&quot;:2
      }
   ]
}&#39;

Statement:

SELECT *
FROM OPENJSON(@json, &#39;$.Fields&#39;) WITH (
  FieldId VARCHAR(10) &#39;$.FieldId&#39;, 
  FieldName VARCHAR(MAX) &#39;$.FieldName&#39;, 
  FieldValue NVARCHAR(MAX) &#39;$.FieldValue&#39;
) j1
CROSS APPLY OPENJSON(j1.FieldValue) WITH (
  Web_Id varchar(50) &#39;$.Web_Id&#39;,
  CCID varchar(50) &#39;$.CCID&#39;
) j2
FieldId FieldName FieldValue Web_Id CCID
17943 &lt;p>Primary_Product&lt;/p>17943 [{"Web_Id":"1;#99999984_6_11_018111","EDF":[{"key":"Orders","val":"1"}],"CCID":"1;#AVSPN004987","G":null}] 1;#99999984_6_11_018111 1;#AVSPN004987

Note, that if the $.FieldValue part of the stored JSON is stored as JSON array, not as a string, you will need the AS JSON modifier to get the nested JSON content.

JSON array as text:

DECLARE @json1 nvarchar(max) = N&#39;{
   &quot;Fields&quot;:[
      {&quot;FieldValue&quot;:&quot;[{\&quot;key\&quot;:\&quot;value\&quot;}]&quot;}
   ]
}&#39;
SELECT *
FROM OPENJSON(@json1, &#39;$.Fields&#39;) WITH (
  FieldValue NVARCHAR(MAX) &#39;$.FieldValue&#39;
) j1
CROSS APPLY OPENJSON(j1.FieldValue) WITH (
  [key] varchar(50) &#39;$.key&#39;
) j2

JSON array as JSON:

DECLARE @json2 nvarchar(max) = N&#39;{
   &quot;Fields&quot;:[
      {&quot;FieldValue&quot;:[{&quot;key&quot;:&quot;value&quot;}]}
   ]
}&#39;
SELECT *
FROM OPENJSON(@json2, &#39;$.Fields&#39;) WITH (
  FieldValue NVARCHAR(MAX) &#39;$.FieldValue&#39; AS JSON
) j1
CROSS APPLY OPENJSON(j1.FieldValue) WITH (
  [key] varchar(50) &#39;$.key&#39;
) j2
FieldValue key
[{"key":"value"}] value

huangapple
  • 本文由 发表于 2023年6月8日 16:17:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76429906.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定