【问题标题】:postgres - how update an item of jsonb list by datepostgres - 如何按日期更新 jsonb 列表项
【发布时间】:2021-10-01 10:14:23
【问题描述】:

我有一张桌子。

create table tb(
  userid int,
  nodes jsonb)

节点示例:

{
 "weight": [{"date":"<date>", value: 50}, {"date":"<date>", value: 60}],
 "height": [{"date":"<date>", value: 170}, {"date":"<date>", value: 172}],
}

我想更改权重列表中某个日期的权重。

或者在特定日期的高度列表中输入一个新值。我该怎么办?

这是我写的。但它只是添加一个新项目。

INSERT INTO tb (UserId, Nodes)
values (1, '{"weight": [{"value":"50","date":"2021-07-24 18:17:33.000"}]}')
ON CONFLICT (UserId) DO UPDATE
    SET Nodes = jsonb_set(tb.Nodes, '{"weight"}',
                          tb.Nodes->'weight' || '{"value":"50","date":"2021-07-24 18:17:43.000"}');

我需要编辑特定日期的值。

【问题讨论】:

  • 您是否考虑过规范化您的数据库架构而不是存储 JSON?
  • 在特定日期的高度列表中输入一个新值” - 您当前的代码已经这样做了,不是吗?
  • 不,真的,这不仅仅是我的数据。为了简单起见,我写了这个。每个用户都有不同的具体信息,但都有一个日期字段。
  • 不,我必须在日期之间搜索并编辑任何具有特定日期的日期,无论时间如何
  • 你的意思是你想为一个日期附加一个新的值,但是如果这个日期的条目已经存在,它应该被覆盖吗? IE。您不知道何时需要更新与何时需要插入?因为插入部分已经在你的代码中工作了。

标签: arrays postgresql jsonb


【解决方案1】:

这是我自己写的。

BEGIN;
LOCK TABLE "UserFitnessData" IN EXCLUSIVE MODE;

do $$
    declare today date;
    declare r jsonb; -- RECORD
    declare idx int :=0;

    begin
        INSERT INTO "UserFitnessData" (UserId, Nodes)
        values (1, '{"FrontImage": [{"value":"50","date":"2021-07-28 18:17:33.000"}]}');
    EXCEPTION WHEN unique_violation THEN
        today := '2021-07-25 18:17:33.000'::date;
        raise notice 'exep >>> %', today;

        FOR r IN
            SELECT jsonb_array_elements(Nodes->'FrontImage') arr FROM "UserFitnessData" WHERE userid = 1
            LOOP
                if (r->>'date')::date = today then
                    
                    UPDATE "UserFitnessData"
                    SET Nodes = Nodes #- FORMAT('{"FrontImage", %s}', idx)::text[] WHERE userid = 1;

                    idx := idx-1;

                    UPDATE "UserFitnessData"
                    SET Nodes = jsonb_set("UserFitnessData".Nodes, '{"FrontImage"}',
                                          "UserFitnessData".Nodes->'FrontImage' || '{"value":"1245","date":"2021-07-27 18:17:43.000"}');
                end if;
                idx := idx+1;
               

        END LOOP;
        RETURN;
    end $$;

COMMIT;

这就是我现在的开始。如果有人有更短的解决方案,请告诉我。

【讨论】:

    猜你喜欢
    • 2020-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-04
    • 2018-03-28
    • 2015-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多