sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL:kenmerk verwijderen uit JSON-kolom

Bijwerken :voor 9.5+ zijn er expliciete operators die u kunt gebruiken met jsonb (als je een json hebt getypte kolom, u kunt casts gebruiken om een ​​wijziging toe te passen):

Het verwijderen van een sleutel (of een index) van een JSON-object (of van een array) kan met de - operator:

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

Verwijderen van diep in een JSON-hiërarchie kan met de #- operator:

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

Voor 9.4 kunt u een aangepaste versie van het oorspronkelijke antwoord gebruiken (hieronder), maar in plaats van een JSON-tekenreeks samen te voegen, kunt u deze samenvoegen tot een json object rechtstreeks met json_object_agg() .

Gerelateerd:andere JSON-manipulaties binnen PostgreSQL:

  • Hoe wijzig ik velden in het nieuwe PostgreSQL JSON-gegevenstype?

Oorspronkelijk antwoord (geldt voor PostgreSQL 9.3):

Als u minimaal PostgreSQL 9.3 heeft, kunt u uw object in paren splitsen met json_each() en filter uw ongewenste velden en bouw de json vervolgens handmatig opnieuw op. Iets als:

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

Met 9.2 (of lager) is dat niet mogelijk.

Bewerken :

Een handiger vorm is om een ​​functie te maken die een willekeurig aantal attributen in een json kan verwijderen veld:

Bewerk 2 :string_agg() is minder duur dan 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$;

Met deze functie hoeft u alleen maar de onderstaande query uit te voeren:

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


  1. Een getal opmaken als een percentage in Oracle

  2. Hoe selecteer ik efficiënt de vorige niet-null-waarde?

  3. Oracle naar PostgreSQL:ANSI outer join-syntaxis in PostgreSQL

  4. Hoe u de juiste gegevenstypen selecteert