2

I am trying to figure out what the query syntax is for an inline sum for a specific field in an object array. My data is structured like this

CREATE TABLE "orders" (
  order_id int8,
  tax_lines jsonb
);
INSERT INTO "orders"(order_id, tax_lines) VALUES (4521745668, '[
  {
    "rate": 0.029,
    "price": "0.43",
    "title": "CO State Tax"
  },
  {
    "rate": 0.00985,
    "price": "0.15",
    "title": "Boulder County Tax"
  },
  {
    "rate": 0.0496,
    "price": "0.74",
    "title": "Boulder Municipal Tax"
  }
]');

The result i am trying to achieve is

order_id         cumulative_tax_rate
4521745668       .08845

This is as far as i have gotten

SELECT
  o.order_id,
  SUM((jsonb_array_elements(o.tax_lines) ->> 'rate')::numeric) AS cumulative_tax_rate
 FROM orders o WHERE o.order_id = '4521745668'

but it keeps asking for a GROUP BY clause which I would like to avoid. I was wondering if it is possible to perform this aggregation at the row level without a group by clause and, if so, what that syntax might look like?

Thank you in advance.

8
  • Is it a typo INSERT INTO >>>> "MY_TABLE" <<<< ? Commented Apr 29, 2017 at 14:58
  • indeed it was, thank you for pointing that out. Edited and fixed. Commented Apr 29, 2017 at 15:06
  • shopify_order_id and jsondata aren't in your orders table Commented Apr 29, 2017 at 15:06
  • 2
    Why you want to avoid the group by? Commented Apr 29, 2017 at 15:14
  • 1
    you need aggregation, not for that one row, but for three array elements in json. check my answer Commented Apr 29, 2017 at 15:14

2 Answers 2

5

Even though you said you want to avoid the group by I will provide a solution with it because it is what you indeed need.

select order_id, 
       sum(tax) tax
  from (SELECT o.order_id, 
               (jsonb_array_elements(o.tax_lines)->>'rate')::numeric tax
          FROM orders o) a
 where order_id = 4521745668 -- this you add if you want a specific order id
  group by order_id;         -- without it you will have all orders tax sum

This will give you the result you want:

  order_id      tax
 4521745668   0.08845

And if you need just add the where clause for that order_id in the outer query. where order_id = 4521745668 no need for quotes since it is a int8 value.

Sign up to request clarification or add additional context in comments.

2 Comments

How would you generate all rows' tax and order_id without summing them all up?
@foureyedraven well, just use the subquery instead.
1

I aggregate with window, not group by - is it what you are looking for?..

t=# with a as (
SELECT
  o.order_id,
 (jsonb_array_elements(o.tax_lines ) ->> 'rate')::float AS cumulative_tax_rate
  FROM orders o WHERE order_id = 4521745668
)
select
distinct order_id, sum(cumulative_tax_rate) over (partition by order_id)
from a;
  order_id  |   sum
------------+---------
 4521745668 | 0.08845
(1 row)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.