SQL Server解析表单元格中多段JSON的result数组为独立行
我来帮你搞定这个问题!你现在遇到的情况是,表中每个单元格的JSON里包含好几个顶级对象,每个对象里又有一个result数组,要把所有result数组里的每一项都拆成单独的数据库行,对吧?你之前写的查询只拿到了最后一条结果,这是因为没把result数组再展开,而且用错了JSON提取的方法。
咱们先说说你原来的问题:你用OPENJSON打开了单元格里的顶级JSON数组,但之后用JSON_VALUE去取$.result[*]."0"——但JSON_VALUE只能返回单个值,它会直接取数组的最后一个元素对应的值,所以就只拿到了最后一条结果,其他都是NULL,而且根本没把result数组里的每一项拆成独立的行。
正确的做法是用两次CROSS APPLY OPENJSON:第一次把单元格里的顶级JSON数组拆成一个个单独的对象,第二次再把每个对象里的result数组拆成一个个单独的结果项,然后再提取每个结果项里的字段。
给你写个完整的查询语句,你直接用就行:
SELECT -- 提取result项中的各个字段,注意键是带引号的数字,所以要写$."0"这种格式 JSON_VALUE(result_item.value, '$."0"') AS date, JSON_VALUE(result_item.value, '$."1"') AS accountID, JSON_VALUE(result_item.value, '$."2"') AS amount, JSON_VALUE(result_item.value, '$."3"') AS description FROM [JSONTable] js -- 第一步:把每个单元格里的顶级JSON数组拆成单个的对象行 CROSS APPLY OPENJSON(js.Data) AS top_level_obj -- 第二步:把每个顶级对象里的result数组拆成单个的结果项行 CROSS APPLY OPENJSON(top_level_obj.value, '$.result') AS result_item
另外要提一句,你给的示例JSON里有语法错误哦——比如"0":2025-07-25"这里,日期字符串前面少了一个双引号,应该是"0":"2025-07-25",这种格式错误会导致SQL Server无法正确解析JSON,所以你得先确保单元格里的JSON格式是正确的,不然查询会出问题。
如果之后你想把fields里的publicPath(比如date、accountID)和result里的数字键对应起来,不用硬编码$."0"这种,还可以再加一层关联,但目前这个查询已经能满足你把所有result项拆成独立行的需求啦。
内容来源于stack exchange

