簡體   English   中英

Postgresql 將 JSONB object 更新為數組

[英]Postgresql update JSONB object to array

我不知道為什么,但可能 PHP 將我的一些數據保存為 object,其中一些保存為數組。 我的桌子看起來像:

seller_info_address 表:

 ID (INT)  |  address (JSONB)                                  |
------------+--------------------------------------------------|
     1      | {"addressLines":{"0":"Technology Park",...},...} |
     2      | {"addressLines":["Technology Park",...],...}     |

一些地址線是對象:

{
  "addressLines": {
    "0": "Technology Park",
    "1": "Blanchard Road",
    "3": "Dublin",
    "4": "2"
  },
  "companyName": "...",
  "emailAddress": [],
  "...": "..."
}

一些地址線是 arrays:

{
  "addressLines": [
    "Technology Park",
    "Blanchard Road",
    "Dublin",
    "2"
  ],
  "companyName": "...",
  "emailAddress": [],
  "...": "..."
}

我想用 SQL 查詢來均衡數據,但我不確定該怎么做。 所有addressLines持久化為 object 應更新為數組形式。

感謝幫助,謝謝!

您可以使用以下方法將對象轉換為數組:

select id, (select jsonb_agg(e.val order by e.key::int) 
            from jsonb_each(sia.address -> 'addressLines') as e(key,val))
from seller_info_address sia
where jsonb_typeof(address -> 'addressLines') = 'object'

where 條件確保我們只對不是數組的地址行執行此操作。

使用的聚合也可以在 UPDATE 語句中使用:

update seller_info_address
  set address = jsonb_set(address, '{addressLines}', 
                          (select jsonb_agg(e.val order by e.key::int) 
                           from jsonb_each(address -> 'addressLines') as e(key,val))
                          )
where jsonb_typeof(address -> 'addressLines') = 'object';

好的,我現在自己找到了解決方案。 絕對不是最 eloquent 的解決方案。 我敢肯定有一個更好,更高效的方法,但是它確實有效...

DROP FUNCTION update_address_object_to_array(id INTEGER);
CREATE OR REPLACE FUNCTION
    update_address_object_to_array(id INTEGER)
    RETURNS VOID AS
$UPDATE_ADDRESS_OBJECT_TO_ARRAY$
BEGIN
    UPDATE seller_info_address
    SET address = jsonb_set(address, '{addressLines}', (
        SELECT CASE
                   WHEN jsonb_agg(addressLines) IS NOT NULL THEN jsonb_agg(addressLines)
                   ELSE '[]'
               END
        FROM seller_info_address sia,
             jsonb_each(address #> '{addressLines}') as t(key, addressLines)
        WHERE jsonb_typeof(sia.address -> 'addressLines') = 'object'
          AND seller_info_id = update_address_object_to_array.id
    ), true)
    WHERE seller_info_id = update_address_object_to_array.id
      AND jsonb_typeof(address -> 'addressLines') = 'object';
END
$UPDATE_ADDRESS_OBJECT_TO_ARRAY$
    LANGUAGE 'plpgsql';
SELECT update_address_object_to_array(sia.seller_info_id)
  FROM seller_info_address sia
 WHERE jsonb_typeof(address -> 'addressLines') = 'object';

內部 SELECT 使用 jsonb_each 獲取addressLines object 中的所有行,然后使用jsonb_each將它們聚合到一個數組jsonb_agg 條件表達式是為了防止 null 個案例。

然后將結果存儲在 UPDATE 中,通過jsonb_set到 json 中所需的 position。WHERES 應該是不言自明的。

暫無
暫無

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

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