微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在JSON列中解压缩所有数组SQL Server 2019

如何解决在JSON列中解压缩所有数组SQL Server 2019

我有一个包含这些列的表Schema.table

id | json_col

在表格上

id=1
json_col ={"names":["John","Peter"],"ages":["31","40"]}

namesages的长度始终相等,但ID之间可能有所不同(大小至少为1,但没有上限)。

我们如何获得“爆炸式”表格-每个“名称”,“年龄”都带有一行的表格,例如

id | names | ages 
---+-------+------
 1 | John  | 31
 1 | Peter | 41
 2 | Jim   | 17
 3 | Foo   |  2
.
.

我尝试了OPEnjsON和CROSS APPLY,但是以下给出了namesages的任意组合,这是不正确的,因此我之后需要进行大量过滤

SELECT *
FROM Schema.table
CROSS APPLY OPEnjsON(Schema.table,'$.names')
CROSS APPLY OPEnjsON(Schema.table,'$.ages')

解决方法

可以使用条件聚合以及应用CROSS APPLY

SELECT id,MAX(CASE WHEN RowKey = 'names' THEN value END) AS names,MAX(CASE WHEN RowKey = 'ages' THEN value END) AS ages
  FROM
  (
   SELECT id,Q0.[value] AS RowArray,Q0.[key] AS RowKey
     FROM tab
    CROSS APPLY OPENJSON(JsonCol) AS Q0
  ) r
 CROSS APPLY OPENJSON(r.RowArray) v
 GROUP BY id,v.[key]   
 ORDER BY id,v.[key]

 id | names | ages 
 ---+-------+------
  1 | John  | 31
  1 | Peter | 41
  2 | Jim   | 17
  3 | Foo   |  2

Demo

OPENJSON的第一个参数将是JSON列值,而不是表本身

,

这是我的建议

DECLARE @tbl TABLE(id INT,json_col NVARCHAR(MAX));
INSERT INTO @tbl VALUES(1,N'{"names":["John","Peter"],"ages":["31","40"]}'),(2,N'{"names":["Jim"],"ages":["17"]}');

SELECT t.id,B.[key] As ValueIndex,B.[value] AS PersonNam,JSON_VALUE(A.ages,CONCAT('$[',B.[key],']')) AS PersonAge
FROM @tbl t
CROSS APPLY OPENJSON(t.json_col) 
            WITH(names NVARCHAR(MAX) AS JSON,ages  NVARCHAR(MAX) AS JSON) A
CROSS APPLY OPENJSON(A.names) B;

简而言之:

  • 我们将OPENJSONWITH子句一起使用,将namesages读入新的json变量中。
  • 我们再使用OPENJSON来“分解”名称数组
  • 由于key是值在数组中的位置,因此我们可以使用JSON_VALUE()通过其位置读取相应的年龄值。

一个一般性说明:如果此JSON受您控制,则应将其更改为以实体为中心的方法(对象数组)。这种与位置有关的存储可能很麻烦……尝试类似

{"persons":[{"name":"John","age":"31"},{"name":"Peter","age":"40"}]}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。