I have seen a lot of references to using json_array_elements on extracting the elements of a JSON array. However, this appears to only work on exactly 1 array. If I use this in a generic query, I get the error
ERROR: cannot call json_array_elements on a scalar
Given something like this:
| orders |
|---|
| { "order_id":"2", "items": [{"name": "apple","price": 1.10}]} |
| { "order_id": "3","items": [{"name": "apple","price": 1.10},{"name": "banana","price": 0.99}]} |
I would like to extract
| item | count |
|---|---|
| apple | 2 |
| banana | 1 |
Or
| item | total_value_sold |
|---|---|
| apple | 2.20 |
| banana | 0.99 |
Is it possible to aggregate over json arrays like this using json_array_elements?
Use the function for orders->'items' to flatten the data:
select elem->>'name' as name, (elem->>'price')::numeric as price
from my_table
cross join jsonb_array_elements(orders->'items') as elem;
It is easy to get the aggregates you want from the flattened data:
select name, count(*), sum(price) as total_value_sold
from (
select elem->>'name' as name, (elem->>'price')::numeric as price
from my_table
cross join jsonb_array_elements(orders->'items') as elem
) s
group by name;
Db<>fiddle.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With