SQL OPENJSON - 解析 JSON 数组

标签 sql json sql-server open-json

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

我陷入困境的地方是将parentIds 数组拉出到单独的行中,并与主ID 字段绑定(bind)。

下面是 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解析也可以。

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

谢谢 杰里米

最佳答案

您需要对每个嵌套级别使用附加的 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

关于SQL OPENJSON - 解析 JSON 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59817138/

相关文章:

mysql - eloquent - 查询生成器运行带绑定(bind)的原始 sql

mysql - 如何选择或区分同一个表中一个字段值相同但另一个字段值不同的两行

mysql - 连接两个表时检索所有数据并按项目计数

php - 如何从 db 表、php 数组或 JSON 中获取分层 php 结构

ios - 如何从登录中获取JSON数据?

没有ORDER BY的Where子句中的SQL Row_Number()函数?

sql-server - 在 Sql STUFF 命令中将最后一项的逗号分隔符替换为 "and"

sql-server - 如何从 TIME 值中获取总毫秒数

php - 这三个sql查询有什么区别?

javascript - 尝试解析大型 JSON 对象并提取数据,但不断收到意外的 token 错误