SQL OPENJSON - 解析 JSON 数组

Posted

技术标签:

【中文标题】SQL OPENJSON - 解析 JSON 数组【英文标题】:SQL OPENJSON - Parse JSON Array 【发布时间】:2020-01-20 04:49:08 【问题描述】:

我希望有人可以帮助我指出正确的方向,即从以下 JSON 示例中解析数组对象。目前,我能够正确解析出大部分 json。

我遇到困难的地方是将 parentId 数组拉出到单独的行中,并绑定到主 ID 字段。

以下是 JSON 的示例。


  "kind": "folders",
  "data": [
    
      "id": "IEABQ5EAI4KGTYGQ",
      "accountId": "IEABQ5EA",
      "title": "test prj",
      "createdDate": "2019-04-17T20:39:58Z",
      "updatedDate": "2020-01-16T22:49:09Z",
      "description": "",
      "sharedIds": [
        "KX74YUWR",
        "KUAD47VS",
        "KX75JYTL",
        "KUAEH2GT",
        "KUAERUOG",
        "KX75EJSV",
        "KX75JYTH",
        "KUAEPBXA",
        "KX74ZXJC",
        "KUADJ7OW",
        "KX75JYTF",
        "KX75JQE2",
        "KX75JYTA",
        "KUAC6PRX",
        "KUAD2ZGS",
        "KUADJYXY",
        "KX75JYS5",
        "KUADQEMC",
        "KUADJXDI",
        "KUADAEPD",
        "KX732DQC",
        "KUACJOOM"
      ],
      "parentIds": [
        "IEABQ5EAI4KGTXVG"
      ],
      "childIds": [],
      "scope": "WsFolder",
      "permalink": "www.test.com",
      "workflowId": "IEABQ5EAK776PC4A",
      "customFields": [],
      "customColumnIds": [],
      "project": 
        "authorId": "KUADJXDI",
        "ownerIds": [
          "KUADJXDI"
        ],
        "status": "Completed",
        "customStatusId": "IEABQ5EAJMA6STFV",
        "startDate": "2019-05-29",
        "endDate": "2019-06-18",
        "createdDate": "2019-05-31T04:56:58Z",
        "completedDate": "2020-01-16T22:49:09Z"
      
    
  ]


下面的 SQL 代码是我用来解析主要字段的代码 --

SELECT [key] AS Doc_id, id, title, createdDate,  updatedDate, [description], permalink, workflowId,
parentIds, customFields, customColumnIds, project
into #JsonDocTemp
FROM OPENJSON (@WJSON2, '$.data') AS EachDoc
  CROSS APPLY OPENJSON(EachDoc.Value)
     WITH (
             id NVARCHAR(20) N'$.id',
             title NVARCHAR(500) N'$.title',
             createdDate DATETIME '$.createdDate',
             updatedDate DATETIME '$.updatedDate',
             [description] NVARCHAR(MAX) N'$.description',
             permalink NVARCHAR(100) N'$.permalink',
             workflowId NVARCHAR(20) N'$.workflowId',
             parentIds NVARCHAR(MAX) N'$.parentIds' AS JSON,
             customFields NVARCHAR(MAX) N'$.customFields' AS JSON,
             customColumnIds NVARCHAR(MAX) N'$.customColumnIds' AS JSON,
             project NVARCHAR(MAX) N'$.parentIds' AS JSON
        )

我想将临时表中的 parentId 解析为行,或者使用 .data.parentId 直接从 @WJSON2 中解析出来。

任何帮助 - 我想我快到了,但我错过了一些东西。

谢谢 杰里米

【问题讨论】:

【参考方案1】:

您需要使用附加的 APPLY 运算符和 OPENJSON() 调用以及每个嵌套级别的显式架构:

JSON:

DECLARE @json nvarchar(max) = N'
   "kind":"folders",
   "data":[
      
         "id":"IEABQ5EAI4KGTYGQ",
         "accountId":"IEABQ5EA",
         "title":"test prj",
         "createdDate":"2019-04-17T20:39:58Z",
         "updatedDate":"2020-01-16T22:49:09Z",
         "description":"",
         "sharedIds":[
            "KX74YUWR",
            "KUAD47VS",
            "KX75JYTL",
            "KUAEH2GT",
            "KUAERUOG",
            "KX75EJSV",
            "KX75JYTH",
            "KUAEPBXA",
            "KX74ZXJC",
            "KUADJ7OW",
            "KX75JYTF",
            "KX75JQE2",
            "KX75JYTA",
            "KUAC6PRX",
            "KUAD2ZGS",
            "KUADJYXY",
            "KX75JYS5",
            "KUADQEMC",
            "KUADJXDI",
            "KUADAEPD",
            "KX732DQC",
            "KUACJOOM"
         ],
         "parentIds":[
            "IEABQ5EAI4KGTXVG"
         ],
         "childIds":[

         ],
         "scope":"WsFolder",
         "permalink":"www.test.com",
         "workflowId":"IEABQ5EAK776PC4A",
         "customFields":[

         ],
         "customColumnIds":[

         ],
         "project":
            "authorId":"KUADJXDI",
            "ownerIds":[
               "KUADJXDI"
            ],
            "status":"Completed",
            "customStatusId":"IEABQ5EAJMA6STFV",
            "startDate":"2019-05-29",
            "endDate":"2019-06-18",
            "createdDate":"2019-05-31T04:56:58Z",
            "completedDate":"2020-01-16T22:49:09Z"
         
      
   ]
'

语句(仅从每个 JSON 级别返回 idparentIds):

SELECT j1.id, j2.parentId
FROM OPENJSON (@json, '$.data') WITH (
   id nvarchar(50) '$.id',
   parentIds nvarchar(max) '$.parentIds' AS JSON
) j1
OUTER APPLY OPENJSON(j1.parentIds) WITH (
   parentId nvarchar(50) '$'
) j2

结果:

id                  parentId
IEABQ5EAI4KGTYGQ    IEABQ5EAI4KGTXVG

语句(解析额外的 JSON 键和嵌套数组):

SELECT 
   j1.kind, 
   j2.id, j2.accountId, j2.title, j2.createdDate, j2.updatedDate, j2.description,
   j3.sharedId, j4.parentId, j5.childId,
   j2.scope, j2.permalink, j2.workflowId,
   j6.customField, j7.customColumnId
FROM OPENJSON (@json, '$') WITH (
   kind nvarchar(50) '$.kind',
   data nvarchar(max) '$.data' AS JSON
)j1
OUTER APPLY OPENJSON(j1.data) WITH (
   id nvarchar(50) '$.id',
   accountId nvarchar(50) '$.accountId',
   title nvarchar(50) '$.title',
   createdDate nvarchar(50) '$.createdDate',
   updatedDate nvarchar(50) '$.updatedDate',
   description nvarchar(50) '$.description',
   sharedIds nvarchar(max) '$.sharedIds' AS JSON,
   parentIds nvarchar(max) '$.parentIds' AS JSON,
   childIds nvarchar(max) '$.childIds' AS JSON,
   scope nvarchar(50) '$.scope',
   permalink nvarchar(50) '$.permalink',
   workflowId nvarchar(100) '$.workflowId',
   customFields nvarchar(max) '$.customFields' AS JSON,
   customColumnIds nvarchar(max) '$.customColumnIds' AS JSON
) j2
OUTER APPLY OPENJSON(j2.sharedIds) WITH (
   sharedId nvarchar(50) '$'
) j3
OUTER APPLY OPENJSON(j2.parentIds) WITH (
   parentId nvarchar(50) '$'
) j4
OUTER APPLY OPENJSON(j2.childIds) WITH (
   childId nvarchar(50) '$'
) j5
OUTER APPLY OPENJSON(j2.customFields) WITH (
   customField nvarchar(50) '$'
) j6
OUTER APPLY OPENJSON(j2.customColumnIds) WITH (
   customColumnId nvarchar(50) '$'
) j7

【讨论】:

谢谢@Zhorov - 这正是我所需要的。

以上是关于SQL OPENJSON - 解析 JSON 数组的主要内容,如果未能解决你的问题,请参考以下文章

使用 OPENJSON 跳过 OBJECTS 解析 JSON SQL

使用 OPENJSON 将 JSON 数组解析为表

SQL Server OPENJSON 读取嵌套的 json

使用 Sql Server 2016 的 OPENJSON 函数从 Json 文档中的多个数组元素中选择结果

如何使用带有交叉应用的 SQL OPENJSON 函数测量 json 文件中数组内数组的长度

SQL Server中的OpenJson用于嵌套的json数据?