我在 postgres 数据库中有一个 JSONB 列。它持有的json对象结构如下:
{
"kws": {},
"distinct": 0,
"count": 0
}
当然,某些记录具有非零/非空值。
一位同事插入了相当多的记录,他将键设为 total_count 而不是 count。有没有办法通过查询来更改该键,而不是检索每条记录并更新字段?
您必须使用魔法
-
和 jsonb 函数 jsonb_insert(); 更新当前内容
CREATE TABLE foo(j jsonb);
INSERT INTO foo(j) VALUES ('{
"kws": {},
"distinct": 0,
"total_count": 0
}'::jsonb)
RETURNING *;
UPDATE foo
SET j = (jsonb_insert(j, '{counter}', j->'total_count')) - 'total_count'
RETURNING *;
新密钥将被命名为
counter
并使用旧值作为总计数。
使用
@?
路径存在运算符来缩小更新范围:demo
update my_table
set jbdata = jsonb_set(jbdata,
'{count}',
coalesce(jbdata->'count',jbdata->'total_count'),
true)-'total_count'
where jbdata @? '$.total_count'
另一种方法(比 @FrankHeikens 所示的
jsonb_insert
+ -
)是使用子查询来扩展所有键值对(使用 jsonb_each
)并重新聚合它们(使用 jsonb_object_agg
),同时字面上重新-键入它们:
UPDATE example
SET foo = (
SELECT jsonb_object_agg(CASE key WHEN 'total_count' THEN 'counter' ELSE key END, value)
FROM jsonb_each(foo)
)
WHERE foo ? 'total_count';
(在线演示)