如何修改 json 数组中与条件匹配的所有值?

How can I modify all values that match a condition inside a json array?

我有一个 table,其中有一个名为 peopleJSON 列,如下所示:

Id people
1 [{ "id": 6 }, { "id": 5 }, { "id": 3 }]
2 [{ "id": 2 }, { "id": 3 }, { "id": 1 }]

...我需要更新 people 列并在路径 $[*].id 中放置一个 0,其中 id = 3,所以执行查询后,table 应该这样结束:

Id people
1 [{ "id": 6 }, { "id": 5 }, { "id": 0 }]
2 [{ "id": 2 }, { "id": 0 }, { "id": 1 }]

每行可能有多个匹配项。

老实说,我没有尝试任何查询,因为我不知道如何在字段内循环,但我的想法是这样的:

UPDATE mytable
    SET people = JSON_SET(people, '$[*].id', 0)

WHERE /* ...something should go here */

这是我的版本

SELECT VERSION()

+-----------------+
|    version()    |
+-----------------+
| 10.4.22-MariaDB |
+-----------------+

official documentation 所述,MySQL 将 JSON-format 字符串存储在字符串列中,因此您可以使用 JSON_SET 函数或任何字符串函数.

对于您的特定任务,应用 REPLACE 字符串函数可能适合您的情况:

UPDATE 
    mytable
SET 
    people = REPLACE(people, CONCAT('"id": ', 3, ' '), CONCAT('"id": ',0, ' '))
WHERE 
    ....;

如果 people 中的 id 值是唯一的,您可以使用 JSON_SEARCH and JSON_REPLACE 的组合来更改值:

UPDATE mytable
SET people = JSON_REPLACE(people, JSON_UNQUOTE(JSON_SEARCH(people, 'one', 3)), 0)
WHERE JSON_SEARCH(people, 'one', 3) IS NOT NULL

请注意,当由于 JSON_SEARCH returning [=17] 而找不到值时,WHERE 子句是必要的,以防止查询将值替换为 NULL =](然后导致 JSON_REPLACE 到 return NULL)。

如果 id 值不唯一,您将不得不依赖字符串替换,最好使用 REGEXP_REPLACE 来处理值中可能存在的间距差异(同时避免替换 3 在(例如)2334:

UPDATE mytable
SET people = REGEXP_REPLACE(people, '("id"\s*:\s*)2\b', '\14')

Demo on dbfiddle