如何在Postgresql中的JSONB数组中求和?

时间:2018-08-11 09:25:29

标签: sql postgresql psql jsonb

在表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)

2 个答案:

答案 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;