簡體   English   中英

以 JSONB 格式更新對象數組 PostgreSQL

[英]Update array of objects in JSONB format PostgreSQL

我需要執行兩個更新操作:

  1. 在第一種情況下將更改數據從字符串更新為布爾值
  2. 基於其他標簽使用新名稱和數據重新創建標簽

jsonb 列中的示例數據:

[
    { "tax": "yes", "tax_percent": 20, "used_when": "after" },
    { "tax": "no", "tax_percent": 20 },
    { "tax_percent": 20, "used_when": "before" }
]

現在:

“稅”值需要從 yes -> true、no 或 null(不存在)更新意味着 -> false

“used_when”需要更新為“using”,如果之后 -> true,如果之前 OR null(不存在)意味着 -> false

所以它看起來像:

[
    { "tax": true, "tax_percent": 20, "using": true },
    { "tax": false, "tax_percent": 20, "using": false },
    { "tax": false, "tax_percent": 20, "using": false }
]

這些值是可選的,因此並非所有條目都有它,這也是數據庫列中的單行,因此需要為每一行更新列中的數據。

分步演示:db<>fiddle

UPDATE t                                                                   -- 5
SET mydata = s.new_data
FROM (
    SELECT
        id,
        json_agg((using_updated - 'used_when')::json) as new_data          -- 4
    FROM t,
        json_array_elements(t.mydata) as elements,                         -- 1
        jsonb_set(elements::jsonb, '{tax}',                                -- 2
            CASE
                WHEN elements ->> 'tax' = 'yes' THEN 'true'::jsonb
                ELSE 'false'::jsonb
            END
        ) as tax_updated,
        jsonb_set(tax_updated::jsonb, '{using}',                           -- 3
            CASE
                WHEN tax_updated ->> 'used_when' = 'true' THEN 'true'::jsonb
                ELSE 'false'::jsonb
            END
        ) as using_updated
    GROUP BY id
) s
WHERE s.id = t.id;
  1. 將所有數組元素提取到每個記錄 2/3 的一個元素中。 現在您可以使用jsonb_set()在數組元素中插入新的或更新現有的屬性。 CASE子句進行條件檢查
  2. 消除剩余的used_when元素。 之后,您可以使用 json_agg 重新聚合更新的元素
  3. UPDATE

如果您的數據類型為 json,則必須對 jsonb 進行強制轉換,因為沒有json_set() 如果沒有,你當然可以忽略演員表。

但是,正如@a_horse_with_no_name 正確提到的那樣:您應該考慮不將這些數據存儲為純 JSON,而是將它們提取到規范化的相對數據庫表結構中,這會使事情變得更容易和更高效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM