在mysql中将合并两个json数组组合为键值,创建一个json对象

7cwmlq89  于 11个月前  发布在  Mysql
关注(0)|答案(4)|浏览(84)

我在MySQL中有两个JSON数组字段,如下所示:

["a", "b", "c"]
["apple", "banana", "coconut"]

字符串
现在我想把它们合并合并成一个JSON对象,如下所示:

{"a":"apple", "b":"banana", "c":"coconut"}


有没有MySQL函数可以实现这个功能?

tez616oj

tez616oj1#

我会用一种简单的方式来处理这个问题。

  • 使用JSON_TABLE()解嵌套两个JSON结构。
  • 把两张table连在一起。
  • 构造适当的JSON对象并聚合。

下面的代码实现了这个逻辑。第一个CTE提取键。第二个CTE提取值,最后将它们组合在一起:

WITH the_keys as (
      SELECT j.*
      FROM t CROSS JOIN
           JSON_TABLE(t.jsdata1,
                      '$[*]'
                      columns (seqnum for ordinality, the_key varchar(255) path '$')
                     ) j
     ),
     the_values as (
      SELECT j.*
      FROM t CROSS JOIN
           JSON_TABLE(t.jsdata2,
                      '$[*]'
                      columns (seqnum for ordinality, val varchar(255) path '$')
                     ) j
     )
select json_objectagg(the_keys.the_key, the_values.val)
from the_keys join
     the_values
     on the_keys.seqnum = the_values.seqnum;

字符串
Here是一个db<>fiddle。
请注意,这是相当普遍的(你可以添加更多的元素到行)。你可以很容易地调整它返回多行数据,如果你在不同的行上有键/值对,并且它没有使用过时的功能。

fv2wmkja

fv2wmkja2#

由于数组中每个元素的索引沿着,以及通过使用information_schema中的表生成行的贡献,您可以通过JSON_EXTRACT()函数进行提取,然后使用从子查询返回的JSON_OBJECTAGG()聚合所有结果,例如

SELECT JSON_OBJECTAGG(Js1,Js2)
  FROM
  (
   SELECT JSON_UNQUOTE(JSON_EXTRACT(jsdata1,CONCAT('$[',@rn+1,']'))) AS Js1, 
          JSON_UNQUOTE(JSON_EXTRACT(jsdata2,CONCAT('$[',@rn+1,']'))) AS Js2, 
          @rn := @rn + 1 AS rn
     FROM tab AS t1
     JOIN (SELECT @rn:=-1) AS r
     JOIN information_schema.tables AS t2
 -- WHERE @rn < JSON_LENGTH(jsdata1) - 1 #redundant for MariaDB, but needed for MySQL
  ) AS j

字符串
哪里
假设'["a", "b", "c"]'是列jsdata1的值,
假设'["apple", "banana", "coconut"]'是列jsdata2的值
在只包含一行的表(tab)中插入。
Demo

ffscu2ro

ffscu2ro3#

如果你需要对这样一个表中的每一行都这样做:
| ID| jkeys|日瓦尔斯|
| --|--|--|
| 1 |[“a”、“B”、“c”]|[“苹果”,“香蕉”,“椰子”]|
| 2 |[“x”,“y”,“z”]|【西瓜、杨梅、西葫芦】|
使用JSON_TABLE对两个数组的数据进行归一化,并在 ordinality 列上连接它们。

select t.id, k.o, k.jkey, v.jval
from t
join json_table(t.jkeys, '$[*]' columns (o for ordinality, jkey text path '$')) k
join json_table(t.jvals, '$[*]' columns (o for ordinality, jval text path '$')) v
  using(o)

字符串
| ID| O| jkey|日瓦勒|
| --|--|--|--|
| 1 | 1 |一|苹果|
| 1 | 2 |B|香蕉|
| 1 | 3 |C|椰子|
| 2 | 1 |X|西瓜|
| 2 | 2 |y|杨梅|
| 2 | 3 |z|西葫芦|
然后你可以按主键(id)分组,并使用JSON_OBJECTAGG()将键值对折叠成一个对象:

select t.id, json_objectagg(k.jkey, v.jval) as j
from t
join json_table(t.jkeys, '$[*]' columns (o for ordinality, jkey text path '$')) k
join json_table(t.jvals, '$[*]' columns (o for ordinality, jval text path '$')) v
  using(o)
group by t.id


| ID| J|
| --|--|
| 1 |{“a”:“苹果”,“B”:“香蕉”,“c”:“椰子”}|
| 2 |{“x”:“西瓜”,“y”:“杨梅”,“z”:“西葫芦”}|
fiddle

hsvhsicv

hsvhsicv4#

使用JSON functions的基本方法如下:

select JSON_OBJECT(
  JSON_UNQUOTE(JSON_EXTRACT(a, '$[0]')), JSON_EXTRACT(b, '$[0]'),
  JSON_UNQUOTE(JSON_EXTRACT(a, '$[1]')), JSON_EXTRACT(b, '$[1]'),
  JSON_UNQUOTE(JSON_EXTRACT(a, '$[2]')), JSON_EXTRACT(b, '$[2]')
) result from tbl;

字符串
SQL sandbox

相关问题