sql >> Base de Datos >  >> RDS >> PostgreSQL

PostgreSQL establece el campo del objeto JSON en la matriz JSON

Esto es posible al recrear la matriz json en cada actualización.

SQL para creación de tablas e inserción de datos de ejemplo:

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

Los datos insertados:

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

Actualizar consulta:

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;

Resultados de la consulta:

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

La consulta funciona de la siguiente manera:

  1. Convierta la matriz json en filas json y fíltrelas por el game propiedad. Esto se hace creando json_rows CTE.

  2. Actualice los datos json en las filas json donde se encuentra el usuario "Joe".

  3. Una vez que tenga los nuevos valores json, simplemente haga una actualización basada en la identificación.

Nota: Como puede ver, en la implementación actual, la matriz json se vuelve a crear (solo en las filas que deben actualizarse). Esto puede provocar un cambio en el orden de los elementos dentro de la matriz.