英文:
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:
{
"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
}
]
}
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 '%Item_Description%' THEN 'Item Description'
WHEN FieldName LIKE '%Item_Number%' THEN 'Item Number'
WHEN FieldName LIKE '%Primary_Product%' THEN 'Primary Product'
ELSE ''
END AS Field
, CASE
WHEN FieldID <> '17943' THEN FieldValue
WHEN FieldID = '17943' THEN SUBSTRING(STUFF(FieldValue, 1, 15, ''), 1, CHARINDEX('"', STUFF(FieldValue, 1, 15, '')) - 1)
ELSE NULL
END AS FieldValue
, SUBSTRING(STUFF(FieldValue, 1, 15, ''), 1, CHARINDEX('"', STUFF(FieldValue, 1, 15, '')) - 1)
FROM CTE_BASE
CROSS APPLY OPENJSON(CTE_BASE.Fields)
WITH (
FieldId VARCHAR(10) '$.FieldId'
, FieldName VARCHAR(MAX) '$.FieldName'
, FieldValue VARCHAR(MAX) '$.FieldValue'
) 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'{
"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
}
]
}'
Statement:
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 | <p>Primary_Product</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'{
"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 array as 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 |
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论