【问题标题】:What is the PostgreSQL call to remove an whole object from a JSONB array of Objects从 JSONB 对象数组中删除整个对象的 PostgreSQL 调用是什么
【发布时间】:2020-10-08 23:44:42
【问题描述】:

表:TEST1 jsonB 列:COLUMN1

[{a: 1, b: 2, c:3},
{a: 4, b: 5, c:6},
{a: 7, b: 8, c:9}]

我想选择 a = 4 的值并删除它所属的整个对象以获得如下结果 [{a: 1, b: 2, c:3}, {a: 7, b: 8, c:9}]

我可以通过WHERE COLUMN1->>'a' = 4找到记录

但我无法弄清楚或如何找到这个基本用例:例如从数组中删除一个对象作为 JSONB 列的一部分

对于一条或多条记录

【问题讨论】:

    标签: arrays json postgresql jsonb delete-record


    【解决方案1】:

    是的,您可以通过 jsonb_array_elements() 函数的贡献将相等替换为不等来反向使用您的过滤逻辑 WHERE COLUMN1->>'a' != 4,然后应用 jsonb_agg() 函数如下:

    SELECT ID, jsonb_agg(elm) AS "Result"
      FROM tab t
     CROSS JOIN jsonb_array_elements(jsdata) AS elm
     WHERE (elm ->> 'a')::int != 4
     GROUP BY ID
    

    Demo

    【讨论】:

    • 我认为这缺少GROUP BY,或者应该使用SELECT (SELECT jsonb_agg(elm) FROM jsonb_array_elements(…) WHERE …) AS result FROM tab 中的子查询
    • 嗨@Bergi,使用GROUP BY 似乎是多余的。你看过演示吗?
    • 是的,你也可以在你的演示中看到它——当tab 中有多行时它会停止工作。 OP 写了“对于一个或多个记录”。
    • 好吧,从这个角度来看你是对的,谢谢@Bergi。我已经编辑了。
    【解决方案2】:

    创建表选项卡(ID INT,jsdata jsonb)

    插入标签值 (1,'[{"a": 1, "b": 2, "c":3},{"a": 4, "b": 5, "c":6},{"a": 7, "b": 8, "c":9}]'::jsonb), (2,'[{"a": 4, "b": 2, "c":3},{"a": 9, "b": 5, "c":6},{"a": 7, "b": 8, "c":9}]'::jsonb)

    更新选项卡 t1 设置 jsdata =(选择 jsonb_agg(榆树) 从标签 t2 交叉连接 jsonb_array_elements(jsdata) AS elm WHERE (elm->>'a')::int != 4 和 t2.ID = 2 按 t2.ID 分组) WHERE t1.ID = 2

    结果: 1,'[{"a": 1, "b": 2, "c":3},{"a": 4, "b": 5, "c":6},{"a": 7 , "b": 8, "c":9}]', 2,'[{"a": 9, "b": 5, "c":6},{"a": 7, "b": 8, "c":9}]'

    【讨论】:

    • Barbaros:是否有更好的方法来更新特定 ID(例如删除数组中的对象)。这行得通,但怀疑这不是最有效的完成方式..
    • 我可以从数组中删除一个对象,如上所示,并用一个具有相同a值的新对象替换它,例如4,但b和c不同。我需要更新 json b 数组内的对象中的多个值。寻找最好的方法来做到这一点
    猜你喜欢
    • 2022-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    • 2020-08-22
    • 2018-07-25
    相关资源
    最近更新 更多