PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL:rimuove l'attributo dalla colonna JSON

Aggiorna :per 9.5+, ci sono operatori espliciti che puoi usare con jsonb (se hai un json colonna digitata, puoi utilizzare i cast per applicare una modifica):

L'eliminazione di una chiave (o di un indice) da un oggetto JSON (o da un array) può essere eseguita con - operatore:

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

L'eliminazione da una gerarchia JSON profonda può essere eseguita con #- operatore:

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

Per 9.4, puoi utilizzare una versione modificata della risposta originale (sotto), ma invece di aggregare una stringa JSON, puoi aggregarla in un json oggetto direttamente con json_object_agg() .

Correlati:altre manipolazioni JSON all'interno di PostgreSQL:

  • Come faccio a modificare i campi all'interno del nuovo tipo di dati JSON di PostgreSQL?

Risposta originale (si applica a PostgreSQL 9.3):

Se hai almeno PostgreSQL 9.3, puoi dividere il tuo oggetto in coppie con json_each() e filtra i campi indesiderati, quindi crea nuovamente il json manualmente. Qualcosa come:

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

Con 9.2 (o inferiore) non è possibile.

Modifica :

Un modulo più conveniente è creare una funzione, che può rimuovere qualsiasi numero di attributi in un json campo:

Modifica 2 :string_agg() è meno costoso di 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$;

Con questa funzione, tutto ciò che devi fare è eseguire la query seguente:

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