将Json嵌套对象数组转换为表行

时间:2018-12-24 07:34:48

标签: sql json sql-server tsql

我有一个像这样的json

[
  {
    "Id": "1234",
    "stockDetail": [
      {
        "Number": "10022_1",
        "Code": "500"
      },
      {
        "Number": "10022_1",
        "Code": "600"
      }
    ]
  },
  {
    "Id": "1235",
    "stockDetail": [
      {
        "Number": "10023_1",
        "Code": "100"
      },
      {
        "Number": "10023_1",
        "Code": "100"
      }
    ]
  }
]

如何在sql表中将其转换,如下所示:

+------+---------+------+
|  Id  | Number  | Code |
+------+---------+------+
| 1234 | 10022_1 |  500 |
| 1234 | 10022_1 |  600 |
| 1235 | 10023_1 |  100 |
| 1235 | 10023_1 |  100 |
+------+---------+------+

2 个答案:

答案 0 :(得分:3)

在您的情况下,您可以尝试将JSON子节点与父节点交叉应用:

DECLARE @json nvarchar(max)
SET @json = N'
[
  {
    "Id": "1234",
    "stockDetail": [
      {
        "Number": "10022_1",
        "Code": "500"
      },
      {
        "Number": "10022_1",
        "Code": "600"
      }
    ]
  },
  {
    "Id": "1235",
    "stockDetail": [
      {
        "Number": "10023_1",
        "Code": "100"
      },
      {
        "Number": "10023_1",
        "Code": "100"
      }
    ]
  }
]'

SELECT
    JSON_Value (i.value, '$.Id') as ID, 
    JSON_Value (d.value, '$.Number') as [Number], 
    JSON_Value (d.value, '$.Code') as [Code]
FROM OPENJSON (@json, '$') as i
CROSS APPLY OPENJSON (i.value, '$.stockDetail') as d

输出:

ID      Number  Code
1234    10022_1 500
1234    10022_1 600
1235    10023_1 100
1235    10023_1 100

答案 1 :(得分:3)

如果需要定义类型化的列,则可以将OPENJSONWITH子句一起使用:

DECLARE @j nvarchar(max) = N'[
  {
    "Id": "1234",
    "stockDetail": [
      { "Number": "10022_1",
        "Code": "500"
      },
      { "Number": "10022_1",
        "Code": "600"
      }
    ]
  },
  {
    "Id": "1235",
    "stockDetail": [
      { "Number": "10023_1",
        "Code": "100"
      },
      { "Number": "10023_1",
        "Code": "100"
      }
    ]
  }
]'

select father.Id, child.Number, child.Code
from openjson (@j) 
with (
    Id          int,
    stockDetail nvarchar(max) as json
) as father
cross apply openjson (father.stockDetail)  
with (
    Number nvarchar(100),
    Code   nvarchar(100)  
) as child

结果:

enter image description here