sql >> Databasteknik >  >> RDS >> PostgreSQL

PostgreSQL:Ta bort attribut från JSON-kolumnen

Uppdatera :för 9.5+ finns det explicita operatorer som du kan använda med jsonb (om du har en json kolumn, kan du använda casts för att tillämpa en ändring):

Att ta bort en nyckel (eller ett index) från ett JSON-objekt (eller från en array) kan göras med - operatör:

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

Att ta bort från djupet av en JSON-hierarki kan göras med #- operatör:

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

För 9.4 kan du använda en modifierad version av det ursprungliga svaret (nedan), men istället för att aggregera en JSON-sträng kan du aggregera till en json objekt direkt med json_object_agg() .

Relaterat:andra JSON-manipulationer inom PostgreSQL:

  • Hur ändrar jag fält i den nya PostgreSQL JSON-datatypen?

Ursprungligt svar (gäller PostgreSQL 9.3):

Om du har minst PostgreSQL 9.3 kan du dela upp ditt objekt i par med json_each() och filtrera dina oönskade fält, bygg sedan upp json igen manuellt. Något i stil med:

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

Med 9.2 (eller lägre) är det inte möjligt.

Redigera :

En mer bekväm form är att skapa en funktion som kan ta bort valfritt antal attribut i en json fält:

Redigera 2 :string_agg() är billigare än 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$;

Med den här funktionen är allt du behöver göra att köra frågan nedan:

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


  1. Hur man installerar MySQL 8 med Workbench på Windows 10

  2. Hur man skapar en riktig en-till-en-relation i SQL Server

  3. Använda modulberoenden, del 2

  4. Skillnad mellan BYTE och CHAR i kolumndatatyper