我确实弄清楚如何从单个记录的数组中删除一个值,但是如何为其中的许多记录删除它。问题在于我如何使用子查询。因为它必须只返回单个元素。也许我的做法是错误的。
Given input: '{attributes:['is_new', 'is_old']}' Expected result '{attributes: ['is_old']}' #remove 'is_new' from jsonb array
Real example: # sku | properties # -------+-------------------------------- # nu3_1 | { + # | "name": "silly_hodgkin", + # | "type": "food", + # | "attributes": [ + # | "is_gluten_free", + # | "is_lactose_free", + # | "is_new" + # | ] + # | }
#Query that removes single array element: SELECT c.sku, jsonb_agg(el) FROM catalog c JOIN (select sku, jsonb_array_elements_text(properties->'attributes') as el from catalog) c2 ON c.sku=c2.sku where el 'is_new' GROUP BY c.sku;
#Update query that removes single array element in single record UPDATE catalog SET properties=jsonb_set(properties, '{attributes}', ( SELECT jsonb_agg(el) FROM catalog c JOIN (select sku, jsonb_array_elements_text(properties->'attributes') as el from catalog) c2 ON c.sku=c2.sku WHERE el 'is_new' AND c.sku='nu3_1' GROUP BY c.sku ) ) WHERE sku='nu3_1';
问题又来了。如何按许多数据库记录的值删除jsonb数组元素?
答案 0 :(得分:11)
使用jsonb_set()
and the delete operator -
:
update catalog
set properties =
jsonb_set(properties, '{attributes}', (properties->'attributes') - 'is_new');
答案 1 :(得分:1)
所以,我相信你正在寻找的QRY是:
with q as (
select distinct sku, jsonb_set(properties,'{attributes}',jsonb_agg(el) over (partition by sku),false) new_properties
from (
select
sku, jsonb_array_elements_text(properties->'attributes') as el, properties
from catalog
) p
where el != 'is_new'
)
update catalog set properties = q.new_properties from q where catalog.sku = q.sku
;
请注意,我认为您的sku
至少是UK
!
答案 2 :(得分:0)
你的解决方案有效+你指出了一些像窗口功能这样的新东西,并给我一个替代解决方案的想法:
WITH q as ( SELECT c.sku as sku, jsonb_set(properties, '{attributes}', jsonb_agg(el)) as new_properties FROM catalog c JOIN (select sku, jsonb_array_elements_text(properties->'attributes') as el from catalog) c2 ON c.sku=c2.sku where el != 'is_new' GROUP BY c.sku ) UPDATE catalog SET properties=q.new_properties FROM q WHERE catalog.sku=q.sku;