PostgreSQL:如何SUM属性包括JSONB字段,并保留表格形状?

时间:2016-02-01 12:44:37

标签: json postgresql postgresql-9.4 jsonb

我正在使用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的正确求和值?

2 个答案:

答案 0 :(得分:1)

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

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

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;

答案 1 :(得分:0)

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

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