如何在 postgres 中对 jsonb 值求和?
Posted
技术标签:
【中文标题】如何在 postgres 中对 jsonb 值求和?【英文标题】:how to sum jsonb values in postgres? 【发布时间】:2021-11-08 06:53:25 【问题描述】:我正在使用 postgres,我需要对 jsonb 字段的值求和
Column │ Type │ Modifiers
─────────────────┼──────────────────────┼────────────────────────────────────────────────────────────────────
id │ integer │ not null default
practice_id │ character varying(6) │ not null
date │ date │ not null
pct_id │ character varying(3) │
astro_pu_items │ double precision │ not null
astro_pu_cost │ double precision │ not null
total │ jsonb │
所以我需要对所有记录的总字段的所有值求和,然后我需要对它们使用聚合函数,例如 min、max 和 avg
我开始这样的查询
select id, json_object_agg(key, val)
from (
select id, key, sum(value::numeric) val
from mytable t, jsonb_each_text(total)
group by id, key
) s
group by id;
在这之后我很困惑。有没有更好的方法来解决这个问题?
我需要在jsonb中添加所有值后使用聚合函数。这可能吗?
I'm getting a result like this
id json_object_agg
25 "a" : 1, "b" : 2
26 "a" : 1, "b" : 2
24 "b" : 2, "a" : 1
我期待这个
id json_object_agg
25 3
26 3
类似的东西
【问题讨论】:
您的内容看起来不错,您的查询有什么问题? 解决问题的更好方法是去掉 JSON 列并以适当的规范化方式存储数据。 @a_horse_with_no_name 你的意思是我应该存储整数而不是 jsonb? @LaurenzAlbe 我需要对此使用聚合函数。 您的查询中有两个聚合函数。缺少什么? 【参考方案1】:要对每一行的total
列的所有值求和,您需要按id
分组,而不是按key
分组:
select t.id, sum(tt.value::numeric) val
from mytable t, jsonb_each(total) AS tt
where jsonb_typeof(tt.value) = 'number' -- to avoid errors in the sum() if non numeric values
group by t.id
要计算表中所有行的最小值、最大值、平均值,您不需要对行进行分组:
select min(s.val), max(s.val), avg(s.val)
from
(
select t.id, sum(tt.value::numeric) val
from mytable t, jsonb_each(total) AS tt
where jsonb_typeof(tt.value) = 'number' -- to avoid errors in the sum() if non numeric values
group by t.id
) as s
【讨论】:
它给了我一个错误 错误:无法将类型 jsonb 转换为数字第 4 行:选择 t.id, sum(tt.value::numeric) val 这是因为postgres版本吗?我用的是旧的 你的 postgres 版本是多少?当值是 jsonb 类型“数字”时,Postgres 应该能够将 jsonb 值转换为数字。您可以尝试通过将jsonb_each
替换为jsonb_each_text
来首先转换为文本。
是的 jsonb_each_test 工作正常。谢谢:)以上是关于如何在 postgres 中对 jsonb 值求和?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Postgres 9.4 中对 JSONB 类型的列执行更新操作
PostgreSQL:如何对包括 JSONB 字段的属性求和,并保留表格形状?