我在一个表(目标)中有一个jsonb
字段,而在另一个表(属性)中有该json字段的“允许”键的定义:
CREATE TABLE attributes (name TEXT);
CREATE TABLE target (custom JSONB);
INSERT INTO attributes VALUES ('a'), ('b'), ('c');
INSERT INTO target VALUES ('{"a": "sth", "b": "sth"}'), ('{"c": "sth"}'), ('{"a": "sth", "d": "sth"}');
因此在此简化示例中,允许的键为a,b and c
。
我现在必须编写一个迁移,该迁移将从target
表中删除没有有效定义的键和值。在这种情况下,这将是密钥d
。
基于此知识,我可以删除d
:
UPDATE target SET custom = custom - 'd';
但是-如何比较两个表并从target.custom
中删除所有键,而在attributes.name
中没有键定义呢?
答案 0 :(得分:1)
您需要首先汇总目标表中每一行应删除的所有键。我假设您在该表中有一些主键列(在下面的示例中为id
)。
此查询:
select id, array_agg(ky)
from target
cross join jsonb_each_text(custom) as c(ky,v)
where c.ky not in (select name from attributes)
group by id;
为每个应删除的ID收集数组中的所有键。现在可以将其用作UPDATE语句的源:
update target
set custom = custom - x.keys
from (
select id, array_agg(ky) as keys
from target
cross join jsonb_each_text(custom) as c(ky,v)
where c.ky not in (select name from attributes)
group by id
) x
where target.id = x.id;