【问题标题】:Get aggregate sum of json array in Postgres NOSQL json data获取 Postgres NOSQL json 数据中 json 数组的总和
【发布时间】:2021-03-24 01:05:47
【问题描述】:

如何在 postgres json 选择中从“refunds”数组中获取聚合 SUM(amount) 以下是我的数据架构和结构:

表名:transactions

列名:data

{
  "id": "tran_6ac25129951962e99f28fa488993",
  "amount": 1200,
  "origin_amount": 3900,
  "status": "partial_refunded",
  "description": "Subscription#sub_a67d59efb2bcbf73485a ",
  "livemode": false,
  "refunds": [
    {
      "id": "refund_ee4192ffb6d2caa490a1",
      "amount": 1200,
      "status": "refunded",
      "created_at": 1426412340,
      "updated_at": 1426412340,
    },
    {
      "id": "refund_0e4a34e4ee7281d369df",
      "amount": 1500,
      "status": "refunded",
      "created_at": 1426412353,
      "updated_at": 1426412353,
    }
  ]
}

输出应该是:1200+1500 = 2700

Output
|---------
|total
|---------
|2700

请提供全局解决方案,不要提供静态数据

【问题讨论】:

    标签: json postgresql nosql


    【解决方案1】:

    这应该适用于 9.3+

    WITH x AS( SELECT
    '{
      "id": "tran_6ac25129951962e99f28fa488993",
      "amount": 1200,
      "origin_amount": 3900,
      "status": "partial_refunded",
      "description": "Subscription#sub_a67d59efb2bcbf73485a ",
      "livemode": false,
      "refunds": [
        {
          "id": "refund_ee4192ffb6d2caa490a1",
          "amount": 1200,
          "status": "refunded",
          "created_at": 1426412340,
          "updated_at": 1426412340
        },
        {
          "id": "refund_0e4a34e4ee7281d369df",
          "amount": 1500,
          "status": "refunded",
          "created_at": 1426412353,
          "updated_at": 1426412353
        }
      ]
    }'::json as y),
    refunds AS(
    SELECT json_array_elements(y->'refunds') as j FROM x)
    SELECT sum((j->>'amount')::int) FROM refunds;
    

    【讨论】:

    • 这里 json 数据是可变的,所以我可以使用“数据”表示字段名称而不是固定字符串。我是 postgres 的新手,你能提供精确的查询列“数据”和动态,而不是静态
    • refunds CTE 从 x.y 中选择,如果你想从 tbl1.data 中选择就这样做WITH refunds AS( SELECT json_array_elements(data->'refunds') as j FROM tbl1) (...)
    • 我跑了WITH x AS( SELECT json_array_elements(data->'refunds') as y FROM transactions ), refunds AS( SELECT json_array_elements(y->'refunds') as j FROM x) SELECT sum((j->>'amount')::int) FROM refunds;并得到了错误ERROR: cannot call json_array_elements on a scalar如果我错了请告诉我
    • @mukund 看来您的数据并不总是像示例中那样。如果您使用的是 9.4,请尝试 SELECT json_array_elements(y->'refunds') as j FROM x WHERE son_typeof(y->'refunds') = 'array
    【解决方案2】:
    WITH AllRefunds AS ( SELECT jsonb_array_elements(data->'refunds') AS refund FROM transactions)
    SELECT SUM( CAST ( refund ->> 'amount' AS INTEGER )) FROM AllRefunds;
    

    如果您需要知道查询是如何构建的:

    1.

    WITH AllRefunds AS ( SELECT jsonb_array_elements(data->'refunds') FROM transactions)
    SELECT * FROM AllRefunds;
    

    这将从交易表中找到的数组refunds 中选择所有元素作为JSON 对象(通过-> 完成)并将其存储在新表AllRefunds 中。这个新表只包含一个未命名的列。

    2.

    WITH AllRefunds AS ( SELECT jsonb_array_elements(data->'refunds') AS refund FROM transactions)
    SELECT * FROM AllRefunds;
    

    这里添加的(第二个)ASAllRefunds 中当前未命名的列重命名为refund

    3.

    WITH AllRefunds AS ( SELECT jsonb_array_elements(data->'refunds') AS refund FROM transactions)
    SELECT SUM( CAST ( refund ->> 'amount' AS INTEGER )) FROM AllRefunds;
    

    我们的数组条目是 JSON 对象。因此,我们将字段 amount 作为带有 ->> 的简单字符串返回,然后我们将其转换为 Integers 和 SUM 所有条目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 2020-06-27
      • 2020-03-07
      • 1970-01-01
      • 2020-09-28
      • 1970-01-01
      • 2015-02-02
      相关资源
      最近更新 更多