I try this
select created_at,
sum((json_array_elements(shipping_lines::json) ->> 'price')::float) as shipping_price
from t1
group by 1
It show Error:
ERROR: aggregate function calls cannot contain set-returning function calls LINE 5: sum(((json_array_elements(shipping_lines::json) ->> 'price')... ^ HINT: You might be able to move the set-returning function into a LATERAL FROM item.
How to fix this using Lateral From? I read this PsSQL docs but not really understand Lateral function
That would be:
select t1.created_at, sum((x.obj->>'price')::float) as shipping_price
from t1
left join lateral jsonb_array_element(t1.shipping_lines::jsonb) as x(obj) on true
group by 1
Or, you can compute the sum()
in the lateral join itself, which avoids the need for outer aggregation (assuming that created_at
is unique in the table to start with):
select t1.created_at, x.shipping_price
from t1
cross join lateral (
select sum((x.obj->>'price')::float) as shipping_price
from jsonb_array_elements(t1.shipping_lines::jsonb) as x(obj)
) x
Note that I slightly changed the query to use jsonb
instead of json
: this new datatype is more flexible and efficient than json
(even if it won't make a real difference here, it should be preferred whenever there is a choice).