如何将 set-returning 函数移动到 LATERAL FROM item PostgreSQL

How to move set-returning function into a LATERAL FROM item PostgreSQL

我试试这个

select created_at, 
sum((json_array_elements(shipping_lines::json) ->> 'price')::float) as shipping_price
from t1
group by 1

它显示错误:

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.

如何使用 Lateral From 解决这个问题?我读过 this PsSQL docs 但不是很了解横向函数

那就是:

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

或者,您可以在横向连接本身中计算 sum(),这避免了外部聚合的需要(假设 created_at 在 table 中是唯一的) :

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

请注意,我稍微更改了查询以使用 jsonb 而不是 json:这个新数据类型比 json 更灵活和高效(即使它不会使真正的区别在这里,有选择的时候应该优先考虑。

嗯。将逻辑移至 from 子句:

select created_at, sum( (j->>'price')::float) as shipping_price
from t1 left join lateral
     json_array_elements(shipping_lines::json) j
     on true
group by 1