簡體   English   中英

如何在Postgresql中的JSONB數組中求和?

[英]How to sum a value in a JSONB array in Postgresql?

鑒於該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)

但是現在我想對這些值求和,可以為空。

如何正確求和數組中的對象字段?

這是表的結構:

                     Table "public.ryzom_characters"
    Column     |          Type          | Collation | Nullable | Default
---------------+------------------------+-----------+----------+---------
 cid           | bigint                 |           |          |
 cname         | character varying(255) |           | not null |
 p06           | jsonb                  |           |          |
 x01           | jsonb                  |           |          |

在from子句的橫向jsonb_array_elements()使用函數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'

函數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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM