【问题标题】:Update certain array elements of a json array in PostgreSQL 9.4在 PostgreSQL 9.4 中更新 json 数组的某些数组元素
【发布时间】:2015-02-02 00:32:05
【问题描述】:

我有一张这样的桌子;

CREATE TABLE test (
  id BIGSERIAL PRIMARY KEY,
  data JSONB
);

INSERT INTO test(data) VALUES('[1,2,"a",4,"8",6]'); -- id = 1
INSERT INTO test(data) VALUES('[1,2,"b",4,"7",6]'); -- id = 2

如何在没有PL/* 的情况下将元素data->1data->3 更新为其他内容?

【问题讨论】:

    标签: arrays postgresql sql-update postgresql-9.4 jsonb


    【解决方案1】:

    您不能直接操作 json / jsonb 类型的选定元素。 Postgres 9.4 中仍然缺少此功能(请参阅@Craig 的评论)。您必须执行 3 个步骤:

    1. 取消嵌套/分解 JSON 值。
    2. 操作选定的元素。
    3. 再次聚合/组合值。

    用 pg 9.4'<new_value>') 用 id = 1 替换 json 数组的 第三个元素 /strong>:

    UPDATE test t
    SET    data = t2.data
    FROM  (
       SELECT id, array_to_json(
                     array_agg(CASE WHEN rn = 1 THEN '<new_value>' ELSE elem END))
                  ) AS data
       FROM   test t2
            , json_array_elements_text(t2.data) WITH ORDINALITY x(elem, rn)         
       WHERE  id = 1
       GROUP  BY 1
       ) t2
    WHERE  t.id = t2.id
    AND    t.data <> t2.data; -- avoid empty updates
    

    关于json_array_elements_text()

    关于WITH ORDINALITY

    【讨论】:

    • 转换 jsonb 值的函数应该在 9.5 中出现。与接受输入并产生输出的任何其他函数没有本质上的不同。主要是还没有人实现替换元素等功能。
    【解决方案2】:

    您可以在 PostgreSQL 9.5 中使用 jsonb_set 执行此操作:

    INSERT INTO test(data) VALUES('[1,2,"a",4,"8",6]');
    UPDATE test SET data = jsonb_set(data, '{2}','"b"', false) WHERE id = 1
    

    用一个简单的选择试试看:

    SELECT jsonb_set('[1,2,"a",4,"8",6]', '{2}','"b"', false)
    -- [1, 2, "b", 4, "8", 6]
    

    如果你想更新两个字段,你可以这样做:

    SELECT jsonb_set(jsonb_set('[1,2,"a",4,"8",6]', '{0}','100', false), '{2}','"b"', false)
    -- [100, 2, "b", 4, "8", 6]
    

    【讨论】:

      猜你喜欢
      • 2015-08-20
      • 1970-01-01
      • 2023-02-13
      • 2016-03-04
      • 2020-07-01
      • 2017-11-02
      • 1970-01-01
      • 2020-07-09
      • 2020-10-21
      相关资源
      最近更新 更多