Postgresql-匹配键上的JSON行总和

时间:2019-02-19 20:28:18

标签: json postgresql

我的数据库中有两列,一个为uid(myuid),另一个为表示每个用户的总宠物数的键值对(totalpetsjson)。我想查询uid,然后对键匹配的JSON行求和。

此查询

SELECT totalpetsjson FROM mytable WHERE "myuid" IN ('john','andy') 

结果分为两行

{'dogs':3,'cats':5,'fish':144}
{'dogs':2,'lizards':4,'cats':3'}

我想要的结果是什么。我如何查询和合并上面的两行,如下所示?

{'dogs':5,'cats':8,'fish':144,'lizards':4}

2 个答案:

答案 0 :(得分:1)

使用函数json_each_text(),该函数给出对(key, value),将values转换为整数,并按keys成组求和。最后,将结果汇总到json:

select json_object_agg(key, sum)
from (
    select key, sum(value::int)
    from my_table 
    cross join json_each_text(totalpetsjson)
    where myuid in ('john','andy') 
    group by key
    ) s

                     json_object_agg                     
---------------------------------------------------------
 { "fish" : 144, "lizards" : 4, "cats" : 8, "dogs" : 5 }
(1 row) 

Live demo in rextester.

答案 1 :(得分:0)

在klin之前的anwser的基础上,如果您对展平整张桌子不感兴趣,但又希望保持分组,则可以扩展该方法:

SELECT x, json_object_agg(key, sum)
FROM (
    SELECT x, key, sum(value::INT) AS sum
    FROM (
        VALUES (1, '{
          "a": 10,
          "b": 11
        }'::JSONB),
        (1, '{
          "b": 12,
          "c": 13
        }'::JSONB),
        (2, '{
          "b": 14,
          "c": 15
        }'::JSONB)
    ) AS mytable(x, y)
             CROSS JOIN jsonb_each_text(Y)
    GROUP BY 1, 2
) x
GROUP BY 1
ORDER BY 1;

结果:

1,"{ ""c"" : 13, ""b"" : 23, ""a"" : 10 }"
2,"{ ""c"" : 15, ""b"" : 14 }"