You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server:将JSON对象数组转换为表格格式出错求助

解决JSON转SQL表格时的NULL值问题

问题场景

现有如下JSON数据:

DECLARE @Jdata NVARCHAR(MAX) = 
'{
  "EmployeeDetails": {
    "BusinessEntityID": 3,
    "NationalIDNumber": 509647174,
    "JobTitle": "Engineering Manager",
    "BirthDate": "1974-11-12",
    "MaritalStatus": "M",
    "Gender": "M",
    "StoreDetail": {
      "Store": [
        {
          "AnnualSales": 800000,
          "AnnualRevenue": 80000,
          "BankName": "Guardian Bank",
          "BusinessType": "BM",
          "YearOpened": 1987,
          "Specialty": "Touring",
          "SquareFeet": 21000
        },
        {
          "AnnualSales": 300000,
          "AnnualRevenue": 30000,
          "BankName": "International Bank",
          "BusinessType": "BM",
          "YearOpened": 1982,
          "Specialty": "Road",
          "SquareFeet": 9000
        }
      ]
    }
  }
}';

需要转换为如下格式的表格:

BusinessEntityID |  AnnualSales  |  BusinessType 
-------------------------------------------------
3                   300000          BM
3                   800000          BM

尝试执行以下SQL代码后,AnnualSales和BusinessType字段返回NULL:

select *
from OPENJSON(@jdata)
WITH( 
BusinessEntityID VARCHAR(20) '$.EmployeeDetails.BusinessEntityID',
AnnualSales integer '$.EmployeeDetails.StoreDetail.Store.AnnualSales',
BusinessType VARCHAR(100) '$.EmployeeDetails.StoreDetail.Store.BusinessType'
) as a

错误输出:

BusinessEntityID |  AnnualSales  |  BusinessType 
-------------------------------------------------
3                   NULL            NULL

错误原因

Store是JSON数组,直接用$.EmployeeDetails.StoreDetail.Store.AnnualSales无法遍历数组内的元素,OPENJSON默认处理顶层对象时,无法直接解析数组内的字段,导致返回NULL。

正确解决方案

方法1:嵌套OPENJSON + CROSS APPLY

先解析外层EmployeeDetails获取BusinessEntityID,并保留Store数组的JSON结构,再通过CROSS APPLY展开数组元素:

SELECT 
  ed.BusinessEntityID,
  s.AnnualSales,
  s.BusinessType
FROM OPENJSON(@Jdata, '$.EmployeeDetails')
WITH (
  BusinessEntityID INT '$.BusinessEntityID',
  Store NVARCHAR(MAX) '$.StoreDetail.Store' AS JSON -- 保留数组的JSON格式
) AS ed
CROSS APPLY OPENJSON(ed.Store)
WITH (
  AnnualSales INT '$.AnnualSales',
  BusinessType VARCHAR(10) '$.BusinessType'
) AS s

方法2:直接定位数组 + JSON_VALUE获取外层字段

直接定位到Store数组,用JSON_VALUE从外层JSON中获取BusinessEntityID,确保每个数组元素都关联同一个ID:

SELECT 
  JSON_VALUE(@Jdata, '$.EmployeeDetails.BusinessEntityID') AS BusinessEntityID,
  AnnualSales,
  BusinessType
FROM OPENJSON(@Jdata, '$.EmployeeDetails.StoreDetail.Store')
WITH (
  AnnualSales INT '$.AnnualSales',
  BusinessType VARCHAR(10) '$.BusinessType'
)

正确输出结果

BusinessEntityID |  AnnualSales  |  BusinessType 
-------------------------------------------------
3                   800000          BM
3                   300000          BM

内容的提问来源于stack exchange,提问作者MAK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 15:25:38