2017-02-24 79 views
1

我嘗試了許多不同的東西,我在這裏和那裏聚會(官方文檔,博客帖子,所以......)但沒有成功,所以這是我的問題給你所有:用postgres乘以json數組的每個項目的值9.6


對於這個表:

basik=# select id, jsonb_pretty(range_price_list_values::jsonb) from product; 
        id     |  jsonb_pretty 
--------------------------------------+-------------------------- 
cc80c862-c264-4bfe-a929-a52478c8d59e | [      + 
             |  {     + 
             |   "to": 10,  + 
             |   "from": 5,  + 
             |   "price": 1  + 
             |  },     + 
             |  {     + 
             |   "to": 20,  + 
             |   "from": 15,  + 
             |   "price": 1298000+ 
             |  },     + 
             |  {     + 
             |   "to": 30,  + 
             |   "from": 25,  + 
             |   "price": 500000 + 
             |  }     + 
             | ] 

如何到乘以1000的每一行的每個元素的price關鍵表?


PS:我失敗暫定爲環顧四周jsonb_ *功能和窗口功能:

WITH prices as (select id, jsonb_array_elements(range_price_list_values::jsonb) from product) 

UPDATE product SET range_price_list_values = JSONB_SET(
    range_price_list_values::jsonb, 
    '{' || price.rank || ',price}', jsonb_extract_path('{' || price.rank || ',price}')::int * 1000, false 
)::json; 

感謝您抽出時間來閱讀! :)

+0

'discrete_price_list_values'是'range_price_list_values'不同?.. –

+0

對不起,這是一個複製粘貼錯字。現在修好。 – Florian

回答

1

你需要一個子選擇,只要你想更新多個字段在你的JSON:

update product 
set range_price_list_values = (
     select jsonb_agg(case 
        when jsonb_typeof(elem -> 'price') = 'number' 
        then jsonb_set(elem, array['price'], to_jsonb((elem ->> 'price')::numeric * 1000)) 
        else elem 
       end) 
     from jsonb_array_elements(range_price_list_values::jsonb) elem 
     )::json; 

:這隻會更新數字price鍵,否則異常將被拋出,當一個價格不是一個數字。

http://rextester.com/PQN70851

+0

太酷了!感謝你及時的答覆 :) – Florian

1

先說出來(很醜陋):具有在CTE

t=# create table product (id text, range_price_list_values jsonb); 
CREATE TABLE 
t=# insert into product select 'cc80c862-c264-4bfe-a929-a52478c8d59e','[ 
t'# { 
t'#  "to": 10, 
t'#  "from": 5, 
t'#  "price": 1 
t'# }, 
t'# { 
t'#  "to": 20, 
t'#  "from": 15, 
t'#  "price": 1298000 
t'# }, 
t'# { 
t'#  "to": 30, 
t'#  "from": 25, 
t'#  "price": 500000 
t'# } 
t'# ]'; 
INSERT 0 1 

t=# with b as (with a as (select id, jsonb_array_elements(range_price_list_values::jsonb) j from product) select id,jsonb_set(j,'{price}',((j->>'price')::int * 1000)::text::jsonb) from a) select distinct id, jsonb_pretty(concat('[',string_agg(jsonb_set::text,',') over (partition by id),']')::jsonb) from b; 
        id     |  jsonb_pretty 
--------------------------------------+----------------------------- 
cc80c862-c264-4bfe-a929-a52478c8d59e | [       + 
             |  {      + 
             |   "to": 10,   + 
             |   "from": 5,   + 
             |   "price": 1000  + 
             |  },      + 
             |  {      + 
             |   "to": 20,   + 
             |   "from": 15,  + 
             |   "price": 1298000000+ 
             |  },      + 
             |  {      + 
             |   "to": 30,   + 
             |   "from": 25,  + 
             |   "price": 500000000 + 
             |  }      + 
             | ] 
(1 row) 

,您可以對更新值它

+0

非常感謝您的快速回答! – Florian

相關問題