【问题标题】:PostgreSQL: How to SUM attributes including a JSONB field, and retain table shape?PostgreSQL:如何对包括 JSONB 字段的属性求和,并保留表格形状?
【发布时间】:2016-02-01 12:44:37
【问题描述】:

我正在使用 Postgres 9.4。我有一个带有 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
 star_pu         │ jsonb                │

我想按日期检索各种属性的总和值,包括 JSONB 数组中的任何内容(可以安全地假设其深度为 1),并以与原始表中相同的结构返回值。

这是我现在使用的查询:

SELECT date,
       SUM(total_list_size) AS total_list_size,
       json_object_agg(key, val)
FROM (
    SELECT date,
           SUM(total_list_size) AS total_list_size,
           key, SUM(value::numeric) val
    FROM frontend_practicelist p, jsonb_each_text(star_pu)
    GROUP BY date, key
    ) p
GROUP BY date
ORDER BY date;

它没有失败,JSON 以字典的形式呈现,这正是我想要的。但是,total_list_size 的总和看起来太大了。我认为它必须被总结两次。

如何在保持相同形状结果的同时获得 total_list_size 的正确总和值?

【问题讨论】:

  • 更新:如果我在外部查询中用AVG 代替SUM,我会得到正确的结果,尽管我不确定这是最有效的处理方式。

标签: json postgresql postgresql-9.4 jsonb


【解决方案1】:

子查询中的函数jsonb_each_text() 导致total_list_size 列的复制次数与star_pu 中的项目数一样多,因此avg() 显示了正确的结果。

要为date 获取一个total_list_size,您可以使用并行子查询来独立累积值。

select *
from (
    select date, json_object_agg(key, val) total_star_pu
    from (
        select date, key, sum(value::numeric) val
        from frontend_practicelist, jsonb_each_text(star_pu)
        group by date, key
        ) s
    group by date
    ) s
    join (
        select date, sum(total_list_size) total_list_size
        from frontend_practicelist
        group by date
        ) t
    using(date)
order by date;

【讨论】:

    【解决方案2】:

    我写了一个Postgres extension 来总结jsons。安装完成后,您只需执行以下操作:

    select date, sum(total_size_list), jsonb_deep_sum(star_pu) from frontend_practicelist;
    

    【讨论】:

      猜你喜欢
      • 2016-05-09
      • 1970-01-01
      • 2020-07-01
      • 2020-01-02
      • 2021-12-27
      • 2019-01-18
      • 1970-01-01
      • 2021-09-23
      • 2017-07-15
      相关资源
      最近更新 更多