在表Addresslist
的jsonb列p06
中给出以下数据:
ryzom_characters
我正在尝试对 -[ RECORD 1 ]------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
p06 | {
"id": 675010,
"cname": "Bob",
"rpjobs": [
{
"progress": 25
},
{
"progress": 13
},
{
"progress": 30
}
]
}
的值求和。我尝试了以下操作:
progress
可以正确列出值:
SELECT
c.cname AS cname,
jsonb_array_elements(c.p06->'rpjobs')::jsonb->'progress' AS value
FROM ryzom_characters c
Where cid = 675010
ORDER BY value DESC
LIMIT 50;
但是现在我想对这些值求和,该值可以为空。
如何正确求和数组中的对象字段?
这是表结构:
cname | value
--------+-------
Savisi | 30
Savisi | 25
Savisi | 13
(3 rows)
答案 0 :(得分:2)
在from子句的横向联接中使用函数jsonb_array_elements()
:
select cname, sum(coalesce(value, '0')::int) as value
from (
select
p06->>'cname' as cname,
value->>'progress' as value
from ryzom_characters
cross join jsonb_array_elements(p06->'rpjobs')
where cid = 675010
) s
group by cname
order by value desc
limit 50;
您可以使用左联接而不是交叉联接来保护查询以防数据不一致:
left join jsonb_array_elements(p06->'rpjobs')
on jsonb_typeof(p06->'rpjobs') = 'array'
where p06->'rpjobs' <> 'null'
答案 1 :(得分:0)
函数jsonb_array_elements()
是一个返回集合的函数。因此,您应该将其用作行源(在FROM
子句中)。调用之后,您将有一个表,其中每一行都包含一个数组元素。从那里开始比较容易。
SELECT cname,
sum(coalesce(r.prog->>'progress'::int, 0)) AS value
FROM ryzom_characters c,
jsonb_array_elements(c.p06->'rpjobs') r (prog)
WHERE c.cid = 675010
GROUP BY cname
ORDER BY value DESC
LIMIT 50;