我的数据库中有两列,一个为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}
答案 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)
答案 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 }"