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

PostgreSQL :Supprimer l'attribut de la colonne JSON

Mettre à jour  :pour 9.5+, il existe des opérateurs explicites que vous pouvez utiliser avec jsonb (si vous avez un json colonne typée, vous pouvez utiliser des transtypages pour appliquer une modification) :

La suppression d'une clé (ou d'un index) d'un objet JSON (ou d'un tableau) peut être effectuée avec le - opérateur :

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

La suppression, depuis le plus profond d'une hiérarchie JSON, peut être effectuée avec le #- opérateur :

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

Pour 9.4, vous pouvez utiliser une version modifiée de la réponse d'origine (ci-dessous), mais au lieu d'agréger une chaîne JSON, vous pouvez agréger dans un json objet directement avec json_object_agg() .

En relation :autres manipulations JSON dans PostgreSQL :

  • Comment puis-je modifier les champs dans le nouveau type de données JSON PostgreSQL ?

Réponse originale (s'applique à PostgreSQL 9.3) :

Si vous avez au moins PostgreSQL 9.3, vous pouvez diviser votre objet en paires avec json_each() et filtrez vos champs indésirables, puis recréez le json manuellement. Quelque chose comme :

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

Avec 9.2 (ou inférieur), ce n'est pas possible.

Modifier :

Une forme plus pratique consiste à créer une fonction, qui peut supprimer n'importe quel nombre d'attributs dans un json champ :

Modifier 2 :string_agg() est moins cher que 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$;

Avec cette fonction, il vous suffit de lancer la requête ci-dessous :

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