PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

PostgreSQL:Attribut aus der JSON-Spalte entfernen

Aktualisieren :für 9.5+ gibt es explizite Operatoren, die Sie mit jsonb verwenden können (wenn Sie eine json typisierte Spalte, können Sie Umwandlungen verwenden, um eine Änderung anzuwenden):

Das Löschen eines Schlüssels (oder eines Index) aus einem JSON-Objekt (oder aus einem Array) kann mit - erfolgen Betreiber:

SELECT jsonb '{"a":1,"b":2}' - 'a', -- will yield jsonb '{"b":2}'
       jsonb '["a",1,"b",2]' - 1    -- will yield jsonb '["a","b",2]'

Das Löschen aus der Tiefe einer JSON-Hierarchie kann mit #- erfolgen Betreiber:

SELECT '{"a":[null,{"b":[3.14]}]}' #- '{a,1,b,0}'
-- will yield jsonb '{"a":[null,{"b":[]}]}'

Für 9.4 können Sie eine modifizierte Version der ursprünglichen Antwort (unten) verwenden, aber anstatt eine JSON-Zeichenfolge zu aggregieren, können Sie in einen json aggregieren Objekt direkt mit json_object_agg() .

Verwandte:andere JSON-Manipulationen innerhalb von PostgreSQL:

  • Wie ändere ich Felder innerhalb des neuen PostgreSQL-JSON-Datentyps?

Originalantwort (gilt für PostgreSQL 9.3):

Wenn Sie mindestens PostgreSQL 9.3 haben, können Sie Ihr Objekt mit json_each() in Paare aufteilen und filtern Sie Ihre unerwünschten Felder und erstellen Sie dann den JSON erneut manuell. Etwas wie:

SELECT data::text::json AS before,
       ('{' || array_to_string(array_agg(to_json(l.key) || ':' || l.value), ',') || '}')::json AS after
FROM (VALUES ('{"attrA":1,"attrB":true,"attrC":["a","b","c"]}'::json)) AS v(data),
LATERAL (SELECT * FROM json_each(data) WHERE "key" <> 'attrB') AS l
GROUP BY data::text

Mit 9.2 (oder niedriger) ist dies nicht möglich.

Bearbeiten :

Eine bequemere Form ist das Erstellen einer Funktion, die eine beliebige Anzahl von Attributen in einem json entfernen kann Feld:

Bearbeiten 2 :string_agg() ist günstiger als array_to_string(array_agg())

CREATE OR REPLACE FUNCTION "json_object_delete_keys"("json" json, VARIADIC "keys_to_delete" TEXT[])
  RETURNS json
  LANGUAGE sql
  IMMUTABLE
  STRICT
AS $function$
SELECT COALESCE(
  (SELECT ('{' || string_agg(to_json("key") || ':' || "value", ',') || '}')
   FROM json_each("json")
   WHERE "key" <> ALL ("keys_to_delete")),
  '{}'
)::json
$function$;

Mit dieser Funktion müssen Sie lediglich die folgende Abfrage ausführen:

UPDATE my_table
SET data = json_object_delete_keys(data, 'attrB');