更新 :9.5以降では、jsonb
で使用できる明示的な演算子があります (json
がある場合 入力された列、キャストを使用して変更を適用できます):
JSONオブジェクト(または配列)からのキー(またはインデックス)の削除は、-
を使用して実行できます。 演算子:
SELECT jsonb '{"a":1,"b":2}' - 'a', -- will yield jsonb '{"b":2}'
jsonb '["a",1,"b",2]' - 1 -- will yield jsonb '["a","b",2]'
JSON階層の深部からの削除は、#-
を使用して実行できます。 演算子:
SELECT '{"a":[null,{"b":[3.14]}]}' #- '{a,1,b,0}'
-- will yield jsonb '{"a":[null,{"b":[]}]}'
9.4では、元の回答の修正バージョン(下記)を使用できますが、JSON文字列を集約する代わりに、json
に集約できます。 json_object_agg()
を使用して直接オブジェクトを作成する 。
関連:PostgreSQLでの他のJSON操作:
- 新しいPostgreSQLJSONデータ型内のフィールドを変更するにはどうすればよいですか?
元の回答 (PostgreSQL 9.3に適用):
少なくともPostgreSQL9.3を使用している場合は、json_each()
を使用してオブジェクトをペアに分割できます。 不要なフィールドをフィルタリングしてから、jsonを手動で再構築します。次のようなもの:
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
9.2(またはそれ以下)ではそれは不可能です。
編集 :
より便利な形式は、json
内の任意の数の属性を削除できる関数を作成することです。 フィールド:
編集2 :string_agg()
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$;
この関数を使用すると、以下のクエリを実行するだけで済みます。
UPDATE my_table
SET data = json_object_delete_keys(data, 'attrB');