更新:对于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}'
对于9.4版本,您可以使用修改过的原答案(如下),但是不要聚合JSON字符串,而是直接使用
json_object_agg()
聚合为一个
json
对象。
相关:在PostgreSQL中进行其他JSON操作:
原始答案(适用于PostgreSQL 9.3):
如果您至少拥有PostgreSQL 9.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');