Това е възможно чрез повторно създаване на json масива при всяка актуализация.
SQL за създаване на таблица и вмъкване на примерни данни:
CREATE TABLE test_table(
id BIGSERIAL PRIMARY KEY ,
game TEXT,
players JSONB
);
INSERT INTO test_table(game, players)
VALUES
('chess', '[{"name": "Joe", "role": "admin"}, {"name": "Mike", "role": "user"}]'),
('football', '[{"name": "Foo", "role": "user"}, {"name": "Bar", "role": "user"}]');
Вмъкнатите данни:
+----+----------+----------------------------------------------------------------------+
| id | game | players |
+----+----------+----------------------------------------------------------------------+
| 1 | chess | [{"name": "Joe", "role": "admin"}, {"name": "Mike", "role": "user"}] |
| 2 | football | [{"name": "Foo", "role": "user"}, {"name": "Bar", "role": "user"}] |
+----+----------+----------------------------------------------------------------------+
Заявка за актуализиране:
WITH json_rows AS
(SELECT id, jsonb_array_elements(players) as json_data FROM test_table
WHERE game = 'chess'),
updated_rows AS (
SELECT
id,
array_to_json(array_agg(
CASE WHEN json_data -> 'name' = '"Joe"'
THEN jsonb_set(json_data, '{role}', '"user"')
ELSE json_data END)) as updated_json
FROM json_rows
GROUP BY id
)
UPDATE test_table SET players = u.updated_json
FROM updated_rows u
WHERE test_table.id = u.id;
Резултати от заявката:
+----+----------+---------------------------------------------------------------------+
| id | game | players |
+----+----------+---------------------------------------------------------------------+
| 2 | football | [{"name": "Foo", "role": "user"}, {"name": "Bar", "role": "user"}] |
| 1 | chess | [{"name": "Joe", "role": "user"}, {"name": "Mike", "role": "user"}] |
+----+----------+---------------------------------------------------------------------+
Заявката работи по следния начин:
-
Преобразувайте json масива в json редове и ги филтрирайте чрез
game
Имот. Това става чрез създаване наjson_rows
CTE. -
Актуализирайте json данните в json редовете, където се намира потребителят „Joe“.
-
След като имате новите json стойности, просто направете актуализация въз основа на идентификатора.
Забележка: Както можете да видите, в текущата реализация json масивът се пресъздава (само в редовете, които трябва да бъдат актуализирани). Това може да доведе до промяна в реда на елементите в масива.