2017-02-24 34 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

相关问题