微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从整个表的 json 对象数组中删除节点

如何解决如何从整个表的 json 对象数组中删除节点

我有一个包含 JSONB 列的表,我在其中存储了一组对象。我想执行一个更新,从该列中删除所有匹配行的特定节点。

以下是获取给定行中元素位置的简单查询:在本例中,我想删除“data”属性 = field_20 的任何节点。

 SELECT position FROM public."Forms",jsonb_array_elements(columnsettings) with ordinality arr(item_object,position) 
WHERE tableid=871 and item_object->>'data' = 'field_20';

然后我可以运行这个查询,它有点适用于单行。如果只有 tableid=871 的一行,并且它找到了 'field_20' 值,则此方法有效。

UPDATE public."Forms" SET columnsettings = columnsettings - 
Cast((SELECT position - 1 FROM public."Forms",position) 
WHERE  tableid=871 and item_object->>'data' = 'field_20') as int)
WHERE tableid=871;

但是,如果 tableid=871 的行不止一行,则会出现以下错误

 more than one row returned by a subquery used as an expression

另外,我发现如果一行实际上不包含“field_20”,最终会重置 columnsettings = null,当我想要的是在没有匹配的情况下不理会它

最终,尝试找到一个查询,该查询将从所有匹配行的 jsonb 列中删除特定的数组元素。

这可能吗?仅供参考,我正在运行 Postgres 版本 11

更新。我还想分享这个问题的先前“解决方案”,因为我之前尝试解决它并认为它有效,但最近发现它没有 这是可行的建议查询

 UPDATE public."Forms"
    SET columnsettings = filtered_elements.columnsettings
    FROM (
        SELECT tableid,JSONB_AGG(el) as columnsettings
        FROM public."Forms",JSONB_ARRAY_ELEMENTS(columnsettings) AS el
        WHERE (el->>'type'='field' and el->>'data' != 'field_20') 
        GROUP BY tableid,columnsettings
    ) AS filtered_elements
    WHERE filtered_elements.tableid = public."Forms".tableid and public."Forms".tableid=871;

然而,当有多行匹配时(在 tableid=871 上),它最终会将每一行上的列设置更新为完全相同的值。我相信它必须从第一场比赛中获取新的列设置,然后将其应用于每一行更新。

期望的结果是从每行的当前列设置中删除节点。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。