【问题标题】:Sum of values of json array in PostgreSQLPostgreSQL中json数组的值总和
【发布时间】:2014-11-02 13:06:24
【问题描述】:

在 PostgreSQL 9.3 中,我有一个这样的表

id | array_json
---+----------------------------
1  | ["{123: 456}", "{789: 987}", "{111: 222}"]
2  | ["{4322: 54662}", "{123: 5121}", "{1: 5345}" ... ]
3  | ["{3232: 413}", "{5235: 22}", "{2: 5453}" ... ]
4  | ["{22: 44}", "{12: 4324}", "{234: 4235}" ... ]
...

我想得到 array_json 列中所有值的总和。因此,例如,对于第一行,我想要:

id | total
---+-------
1  | 1665

其中1665 = 456 + 987 + 222(json数组所有元素的值)。没有关于 json 元素的键的先前信息(只是随机数)

我正在阅读有关 JSON functions in PostgreSQL 9.3 的文档页面,我认为我应该使用 json_each,但找不到正确的查询。你能帮我解决一下吗?

在此先感谢

【问题讨论】:

    标签: arrays json postgresql


    【解决方案1】:

    您开始寻找正确的地方(访问文档总是正确的地方)。

    由于您的值是 JSON 数组 -> 我建议使用 json_array_elements(json)

    由于它是一个 json 数组,您必须将其分解为几行,然后通过在 json_each_text(json) 上运行 sum 来组合回来 - 最好创建自己的函数(Postgres 允许)

    至于您的具体情况,假设您提供的结构是正确的,可以使用一些字符串解析+ JSON 繁重的魔法(假设您的表名是“json_test_table”,列是“id”和“json_array”),这是执行您的“事情”的查询

    select id, sum(val) from 
        (select id,
         substring(
            json_each_text(
              replace(
               replace(
                replace(
                 replace(
                  replace(json_array,':','":"')
                 ,'{',''),
                '}','')
               ,']','}')
              ,'[','{')::json)::varchar 
         from '\"(.*)\"')::int  as val  
       from json_test_table) j group by id ; 
    

    如果您打算在庞大的数据集上运行它 - 请记住字符串操作在性能方面的成本很高

    【讨论】:

    • 太棒了!我找到了一个解决方案,但使用中间表和/或带有子句。这更优雅。非常感谢!
    • @jorgeas80 看看我的回答,也许你也会觉得它更优雅:)
    【解决方案2】:

    你可以用这个得到它:

    /*
    Sorry, sqlfiddle is busy :p
    CREATE TABLE my_table
    (
      id bigserial NOT NULL,
      array_json json[]
      --,CONSTRAINT my_table_pkey PRIMARY KEY (id)
    )
    
    INSERT INTO my_table(array_json)
       values (array['{"123": 456}'::json, '{"789": 987}'::json, '{"111": 222}'::json]);
    */   
    
    select id, sum(json_value::integer)
    from
    (
    select id, json_data->>json_object_keys(json_data) as json_value from
        (
        select id,  unnest(array_json) as json_data from my_table
        ) A
    ) B 
    group by id
    

    【讨论】:

      猜你喜欢
      • 2017-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-30
      • 1970-01-01
      • 2020-08-30
      相关资源
      最近更新 更多