SQL Server JSON 数组
Posted
技术标签:
【中文标题】SQL Server JSON 数组【英文标题】:SQL Server JSON Array 【发布时间】:2018-10-05 18:31:00 【问题描述】:我有一些 JSON 想在 SQL Server 2016 中解析。有一个带有数组的层次结构。我想编写一个更有效地解析整个层次结构的查询,我在尝试访问嵌入式数组时遇到了挑战,尤其是“DealerPrefLocation”下的任何内容,而访问“DealerInformation”下的任何内容都没有问题,如下是我的示例 JSON:
"DealerInformation":
"Altername": [
"firstName": "two",
"lastName": "one",
"middleName": null,
"otherNameExplanation": "change"
],
"DealerType":
"id": "87ab-098ng-2345li",
"name": "DMD"
,
"firstName": "PK",
"middleName": null,
"lastName": "KPK",
"primaryDealerState": "AP",
"otherDealerState": [
"AP",
"MP"]
,
"DealerPrefLocation": [
"PrefLocation": [
"address":
"address1": "fort warangal",
"address2": "east",
"addressStandardizationSource": null,
"city": "warangal",
"country": "India"
,
"apptPhoneNumber": "989898989898",
"createdAt": null,
"phoneNumber": "989898989898"
],
"NonPrefLocation": [
"address":
"address1": "fort Junction",
"address2": null,
"addressStandardizationSource": null
,
"createdAt": null,
"ServiceName": "H1",
"ServiceId": [
"ServiceGroupName": null,
"Type": "GROUP",
"ServiceNumber": "9999999"
]
],
"Inserted": null,
"Updated": null
]
我确实知道如何查询“DealerInformation”和其中的数组,例如“AlterName”和“OtherDealerState”,但是我在查询“DealerInformation”-->“PrefLocation”-->Address 下的数组时遇到了挑战。
请找到我当前的查询和输出:
select
ID,
JSON_VALUE(VALUE_ID,'$.DealerInformation.firstName'),
JSON_VALUE(VALUE_ID,'$.DealerInformation.primaryDealerState'),
JSON_VALUE(A.VALUE,'$.firstName'),
JSON_VALUE(C.VALUE,'$.PrefLocation.address.address1')
from
Test_JSON_File
cross apply
openjson(Test_JSON_File.value_id,'$.DealerInformation.Altername')A
cross apply
openjson(Test_JSON_File.Test_JSON_CAQH.value_id,'$.DealerPrefLocation')C
我选择的最后一列来自“DealerPrefLocation”,但我只得到空值,谁能帮助我在 SQL 中缺少什么或我需要添加什么?
【问题讨论】:
【参考方案1】:抱歉,这个答案来晚了……
我认为,对您来说最重要的信息是WITH
子句中的AS JSON
。看看我是如何使用它的:
DECLARE @json NVARCHAR(MAX) =
N'
"DealerInformation":
"Altername": [
"firstName": "two",
"lastName": "one",
"middleName": null,
"otherNameExplanation": "change"
],
"DealerType":
"id": "87ab-098ng-2345li",
"name": "DMD"
,
"firstName": "PK",
"middleName": null,
"lastName": "KPK",
"primaryDealerState": "AP",
"otherDealerState": [
"AP",
"MP"]
,
"DealerPrefLocation": [
"PrefLocation": [
"address":
"address1": "fort warangal",
"address2": "east",
"addressStandardizationSource": null,
"city": "warangal",
"country": "India"
,
"apptPhoneNumber": "989898989898",
"createdAt": null,
"phoneNumber": "989898989898"
],
"NonPrefLocation": [
"address":
"address1": "fort Junction",
"address2": null,
"addressStandardizationSource": null
,
"createdAt": null,
"ServiceName": "H1",
"ServiceId": [
"ServiceGroupName": null,
"Type": "GROUP",
"ServiceNumber": "9999999"
]
],
"Inserted": null,
"Updated": null
]
';
--我将从每个区域中至少选择一个元素。这应该为您指明方向:
SELECT B.firstName
,B.middleName
,B.lastName
,JSON_VALUE(B.DealerType,'$.id') AS DealerTypeId
,B.PrimaryDealerState
,B.otherDealerState --You can dive deeper to parse that array
,JSON_VALUE(B.Altername,'$[0].firstName') AS Alter_firstName --there might be more...
,JSON_VALUE(C.PrefLocation,'$[0].address.address1') AS pref_address --there might be more...
,JSON_VALUE(C.PrefLocation,'$[0].apptPhoneNumber') AS pref_apptPhoneNumber
,JSON_VALUE(C.NonPrefLocation,'$[0].address.address1') AS nonpref_address --there might be more...
,JSON_VALUE(C.NonPrefLocation,'$[0].ServiceName') AS nonpref_ServiceName
FROM OPENJSON(@json)
WITH(DealerInformation NVARCHAR(MAX) AS JSON
,DealerPrefLocation NVARCHAR(MAX) AS JSON) A
OUTER APPLY OPENJSON(A.DealerInformation)
WITH(Altername NVARCHAR(MAX) AS JSON
,DealerType NVARCHAR(MAX) AS JSON
,firstName NVARCHAR(MAX)
,DealerType NVARCHAR(MAX) AS JSON
,middleName NVARCHAR(MAX)
,lastName NVARCHAR(MAX)
,primaryDealerState NVARCHAR(MAX)
,otherDealerState NVARCHAR(MAX) AS JSON) B
OUTER APPLY OPENJSON(A.DealerPrefLocation)
WITH(PrefLocation NVARCHAR(MAX) AS JSON
,NonPrefLocation NVARCHAR(MAX) AS JSON) C
UPDATE 从表中选择
试试这个
SELECT B.firstName
,B.middleName
,B.lastName
,JSON_VALUE(B.DealerType,'$.id') AS DealerTypeId
,B.PrimaryDealerState
,B.otherDealerState --You can dive deeper to parse that array
,JSON_VALUE(B.Altername,'$[0].firstName') AS Alter_firstName --there might be more...
,JSON_VALUE(C.PrefLocation,'$[0].address.address1') AS pref_address --there might be more...
,JSON_VALUE(C.PrefLocation,'$[0].apptPhoneNumber') AS pref_apptPhoneNumber
,JSON_VALUE(C.NonPrefLocation,'$[0].address.address1') AS nonpref_address --there might be more...
,JSON_VALUE(C.NonPrefLocation,'$[0].ServiceName') AS nonpref_ServiceName
FROM Test_JSON_File
CROSS APPLY OPENJSON(value_id)
WITH(DealerInformation NVARCHAR(MAX) AS JSON
,DealerPrefLocation NVARCHAR(MAX) AS JSON) A
OUTER APPLY OPENJSON(A.DealerInformation)
WITH(Altername NVARCHAR(MAX) AS JSON
,DealerType NVARCHAR(MAX) AS JSON
,firstName NVARCHAR(MAX)
,DealerType NVARCHAR(MAX) AS JSON
,middleName NVARCHAR(MAX)
,lastName NVARCHAR(MAX)
,primaryDealerState NVARCHAR(MAX)
,otherDealerState NVARCHAR(MAX) AS JSON) B
OUTER APPLY OPENJSON(A.DealerPrefLocation)
WITH(PrefLocation NVARCHAR(MAX) AS JSON
,NonPrefLocation NVARCHAR(MAX) AS JSON) C;
【讨论】:
非常感谢,如何将这种语法应用于我的表?你能帮忙吗,在这种情况下它对变量值起作用,但我的数据在一个名为“Test_JSON_File”的表中名为“value_id”的列中 非常感谢Shnugo,请再问一个问题,有没有办法我可以简单地查询而不需要提及数组的索引?从自动化的角度思考,我可以编写没有任何索引号的查询并取回数组中的所有值。以上是关于SQL Server JSON 数组的主要内容,如果未能解决你的问题,请参考以下文章
用于 JSON 输出整数数组的 SQL Server 2016
使用 JSON_VALUE 访问 SQL Server 2016 中的 JSON 数组
在 SQL Server 2016 中获取 json 数组的长度
JSON 到 SQL Server 2016 缺少数组中的行