sql >> Databasteknik >  >> RDS >> PostgreSQL

PostgreSQL-uppsättningsfält för JSON-objekt i JSON-array

Detta är möjligt genom att återskapa json-arrayen vid varje uppdatering.

SQL för tabellskapande och exempeldatainfogning:

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

De infogade uppgifterna:

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

Uppdatera fråga:

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;

Resultat av frågan:

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

Frågan fungerar på följande sätt:

  1. Konvertera json-arrayen till json-rader och filtrera dem efter game fast egendom. Detta görs genom att skapa json_rows CTE.

  2. Uppdatera json-data i json-raderna där användaren "Joe" finns.

  3. När du har de nya json-värdena, gör bara en uppdatering baserat på id.

Obs! Som du kan se, i den nuvarande implementeringen återskapas json-arrayen (endast i de rader som behöver uppdateras). Detta kan orsaka en förändring i ordningen för elementen inuti arrayen.




  1. jooq - problem med att känna igen postgres UNIKA begränsning

  2. Hur man använder variabler i WHERE-satsen för en SQL SELECT-fråga

  3. Loopar på värden, skapar dynamiska frågor och lägger till resultatuppsättningen

  4. Hur man krypterar en användardefinierad funktion i SQL Server