Postgresql -对匹配键上的JSON行求和

50pmv0ei  于 2023-04-13  发布在  PostgreSQL
关注(0)|答案(2)|浏览(195)

我的数据库中有两列,一列是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}
qxsslcnc

qxsslcnc1#

使用函数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)

db<>fiddle.中测试

sg2wtvxw

sg2wtvxw2#

在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 }"

相关问题