如何在 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 字段的属性求和,并保留表格形状?

如何从 postgres JSONB 列中获取值?

如何将postgres jsonb字段的属性插入键值表?

如何根据 jsonb 列中的 unix 整数设置 postgres 时间戳列?

在 Postgres 中优化 jsonb 数组值的 GROUP BY