PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

PostgreSQL définit le champ de l'objet JSON dans le tableau JSON

Ceci est possible en recréant le tableau json à chaque mise à jour.

SQL pour la création de table et exemple d'insertion de données :

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"}]');

Les données insérées :

+----+----------+----------------------------------------------------------------------+
| id |   game   |                               players                                |
+----+----------+----------------------------------------------------------------------+
|  1 | chess    | [{"name": "Joe", "role": "admin"}, {"name": "Mike", "role": "user"}] |
|  2 | football | [{"name": "Foo", "role": "user"}, {"name": "Bar", "role": "user"}]   |
+----+----------+----------------------------------------------------------------------+

Mettre à jour la requête :

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;

Résultats de la requête :

+----+----------+---------------------------------------------------------------------+
| id |   game   |                               players                               |
+----+----------+---------------------------------------------------------------------+
|  2 | football | [{"name": "Foo", "role": "user"}, {"name": "Bar", "role": "user"}]  |
|  1 | chess    | [{"name": "Joe", "role": "user"}, {"name": "Mike", "role": "user"}] |
+----+----------+---------------------------------------------------------------------+

La requête fonctionne de la manière suivante :

  1. Convertissez le tableau json en lignes json et filtrez-les par le game propriété. Cela se fait en créant le json_rows CTE.

  2. Mettez à jour les données json dans les lignes json où se trouve l'utilisateur "Joe".

  3. Une fois que vous avez les nouvelles valeurs json, faites simplement une mise à jour basée sur l'id.

Remarque : Comme vous pouvez le voir, dans l'implémentation actuelle, le tableau json est recréé (uniquement dans les lignes qui doivent être mises à jour). Cela peut entraîner une modification de l'ordre des éléments à l'intérieur du tableau.