Postgres PLpgSQL JSON SUM

时间:2016-11-29 10:33:20

标签: json postgresql plpgsql

我试图计算PLpgSQL中的一些JSON值的总和(Postgres v9.5.5),但我仍然坚持逻辑。

对于此数据集:

{
  clientOrderId: 'OR836374647',
  status: 'PENDING',
  clientId: '583b52ede4b1a3668ba0dfff',
  sharerId: '583b249417329b5b737ad3ee',
  buyerId: 'abcd12345678',
  buyerEmail: 'test@test.com',
  lineItems: [{
    name: faker.commerce.productName(),
    description: faker.commerce.department(),
    category: 'test',
    sku: faker.random.alphaNumeric(),
    quantity: 3
    price: 40
    status: 'PENDING'
  }, {
    name: faker.commerce.productName(),
    description: faker.commerce.department(),
    category: 'test',
    sku: faker.random.alphaNumeric(),
    quantity: 2,
    price: 30,
    status: 'PENDING'
  }

我正在尝试获取每一行的所有lineItem的小计(即每个订单项的数量*价格,然后是该行的这些值的总和)。因此,对于上面的示例,返回的值应为180。

我得到了这个,但是这会返回表中所有lineItem的总计,而不是按行分组。

WITH line_items AS (SELECT jsonb_array_elements(line_items) as line_items FROM public.order),
line_item_totals AS (SELECT line_items->>'quantity' AS quantity, line_items->>'price' AS price FROM line_items)

SELECT (quantity::int * price::numeric) AS sub_total FROM line_item_totals;

我确定修复很简单,但我不确定如何使用JSON字段执行此操作。

1 个答案:

答案 0 :(得分:0)

请始终包含您正在使用的Postgres版本。它看起来像你的JSON是不正确的。以下是使用json类型和有效 json文档完成此操作的示例。

with t(v) as ( VALUES
  ('{
      "clientOrderId": "OR836374647",
      "status": "PENDING",
      "clientId": "583b52ede4b1a3668ba0dfff",
      "sharerId": "583b249417329b5b737ad3ee",
      "buyerId": "abcd12345678",
      "buyerEmail": "test@test.com",
      "lineItems": [{
          "name": "name1",
          "description": "desc1",
          "category": "test",
          "sku": "sku1",
          "quantity": 3,
          "price": 40,
          "status": "PENDING"
        },
        {
          "name": "name2",
          "description": "desc2",
          "category": "test",
          "sku": "sku2",
          "quantity": 2,
          "price": 30,
          "status": "PENDING"
        }]
      }'::JSON)
)
SELECT
  v->>'clientOrderId' cId,
  sum((item->>'price')::INTEGER * (item->>'quantity')::INTEGER) subtotal
FROM
  t,
  json_array_elements(v->'lineItems') item
GROUP BY cId;

结果:

     cid     | subtotal 
-------------+----------
 OR836374647 |      180
(1 row)