修改 mysql 中 json 数组中的每个对象
modify every object in json array in mysql
Json 数组 - [{"a":1},{"a":2}]
有没有一种方法可以通过单个查询 update/set 此数组中的每个对象?
我可以使用 `
更新特定对象
SELECT JSON_SET('[{"a":1},{"a":2}]','$[0].b','new val')
结果
[{"a": 1, "b": "new val"}, {"a": 2}]
但我需要
[{"a": 1, "b": "new val"}, {"a": 2, "b": "new val"}]
。我用的是mysql 8.0.22
这是我测试过的解决方案:
mysql> set @j='[{"a":1},{"a":2}]';
mysql> with recursive cte as (
select 0 as i, json_set(@j, '$[0].b', 'new val') as j
union all
select cte.i+1, json_set(cte.j, concat('$[',cte.i+1,'].b'), 'new val')
from cte
where cte.i<json_length(@j)-1
) select * from cte
where i = json_length(@j)-1;
+------+------------------------------------------------------+
| i | j |
+------+------------------------------------------------------+
| 1 | [{"a": 1, "b": "new val"}, {"a": 2, "b": "new val"}] |
+------+------------------------------------------------------+
我不得不说这回避了 JSON 是否值得的问题。如果您使用普通的行和列而不是 JSON.
会容易得多
如果你有多个“a”那么先做一个JSONtable然后再组合回去。
随着 miore 复杂化和嵌套 json 你必须在 JSON_TABLE
上做更多的工作
SELECT JSON_SET('[{"a":1},{"a":2}]','$[0].b','new val');
| JSON_SET('[{"a":1},{"a":2}]','$[0].b','new val') |
| :----------------------------------------------- |
| [{"a": 1, "b": "new val"}, {"a": 2}] |
SELECT
JSON_ARRAYAGG(JSON_OBJECT("a", a, "b", "new valuze"))
FROM
JSON_TABLE(
'[{"a":1},{"a":2}]',
"$[*]" COLUMNS(
a VARCHAR(100) PATH "$.a"
)
) AS jt1;
| JSON_ARRAYAGG(JSON_OBJECT("a", a, "b", "new valuze")) |
| :------------------------------------------------------------- |
| [{"a": "1", "b": "new valuze"}, {"a": "2", "b": "new valuze"}] |
db<>fiddle here
Json 数组 - [{"a":1},{"a":2}]
有没有一种方法可以通过单个查询 update/set 此数组中的每个对象?
我可以使用 `
更新特定对象SELECT JSON_SET('[{"a":1},{"a":2}]','$[0].b','new val')
结果
[{"a": 1, "b": "new val"}, {"a": 2}]
但我需要
[{"a": 1, "b": "new val"}, {"a": 2, "b": "new val"}]
。我用的是mysql 8.0.22
这是我测试过的解决方案:
mysql> set @j='[{"a":1},{"a":2}]';
mysql> with recursive cte as (
select 0 as i, json_set(@j, '$[0].b', 'new val') as j
union all
select cte.i+1, json_set(cte.j, concat('$[',cte.i+1,'].b'), 'new val')
from cte
where cte.i<json_length(@j)-1
) select * from cte
where i = json_length(@j)-1;
+------+------------------------------------------------------+
| i | j |
+------+------------------------------------------------------+
| 1 | [{"a": 1, "b": "new val"}, {"a": 2, "b": "new val"}] |
+------+------------------------------------------------------+
我不得不说这回避了 JSON 是否值得的问题。如果您使用普通的行和列而不是 JSON.
会容易得多如果你有多个“a”那么先做一个JSONtable然后再组合回去。
随着 miore 复杂化和嵌套 json 你必须在 JSON_TABLE
上做更多的工作SELECT JSON_SET('[{"a":1},{"a":2}]','$[0].b','new val');
| JSON_SET('[{"a":1},{"a":2}]','$[0].b','new val') | | :----------------------------------------------- | | [{"a": 1, "b": "new val"}, {"a": 2}] |
SELECT JSON_ARRAYAGG(JSON_OBJECT("a", a, "b", "new valuze")) FROM JSON_TABLE( '[{"a":1},{"a":2}]', "$[*]" COLUMNS( a VARCHAR(100) PATH "$.a" ) ) AS jt1;
| JSON_ARRAYAGG(JSON_OBJECT("a", a, "b", "new valuze")) | | :------------------------------------------------------------- | | [{"a": "1", "b": "new valuze"}, {"a": "2", "b": "new valuze"}] |
db<>fiddle here