postgresql 如何根据键对json对象求和?

erhoui1w  于 2023-08-04  发布在  PostgreSQL
关注(0)|答案(2)|浏览(132)

给定一个包含json对象的列,如何使用sql基于键对它们求和?

Table 3
-------
id, values
1, {"A": 10, "B": -5}
2, {"A": 20}
3, {"A": -15, "B": -5}
4, {"A": -10, "C": 77}

字符串
此外,按另一个表关系对总和重新分组

Table1 has many Table3.
Table1 <-------- Table2 --------> Table 3

Table 1
-------
id
1
2 

Table 2
-------
id, table1_key, table3_key
1, 2, 3
2, 1, 4


测试结果:

Table 1 sums:
1, {"A": 5, "B": -5} # only sum of Table 3 id=2 and id=3
2, {"A": 0, "B": -5, "C": 77} # only sum of Table 3 id=1 and id=4

w6lpcovy

w6lpcovy1#

您可以首先通过聚合执行求和,然后使用jsonb_object_agg将结果组合到单个JSON对象中:

select t4.id, jsonb_object_agg(t4.key, t4.val) from (
    select t2.id, v.key, sum(v.value::int) val from table2 t2 
    join table3 t3 on t3.id in (t2.table1_key, t2.table3_key)
    cross join jsonb_each(t3.js) v
    group by t2.id, v.key) t4
group by t4.id
order by t4.id

字符串
See fiddle

3qpi33ja

3qpi33ja2#

为此使用jsonb_each_text()和必要的强制转换:

with indata (j) as (
  values 
  ('{"A": 10, "B": -5}'::jsonb), ('{"A": 20}'),
  ('{"A": -15, "B": -5}'), ('{"A": -10, "C": 77}')
)
select k, sum(v::int)
  from indata
       cross join lateral jsonb_each_text(j) as e(k,v)
 group by k;

字符串
工作fiddle

相关问题