【问题标题】:How to move set-returning function into a LATERAL FROM item PostgreSQL如何将集合返回函数移动到 LATERAL FROM 项目 PostgreSQL
【发布时间】:2021-02-10 17:07:45
【问题描述】:

我试试这个

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

显示错误:

错误:聚合函数调用不能包含集合返回函数 调用第 5 行: sum(((json_array_elements(shipping_lines::json) ->> '价钱')... ^ 提示:您也许可以将 set-returning 函数移动到 LATERAL FROM 项中。

如何使用横向从解决这个问题?看了this PsSQL docs,但不是很懂横向函数

【问题讨论】:

    标签: sql arrays json postgresql lateral-join


    【解决方案1】:

    那就是:

    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 在表中是唯一的):

    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 更灵活和高效(即使在这里不会产生真正的区别,它应该是首选只要有选择)。

    【讨论】:

    • 为什么第一个答案是LEFT JOIN on True 而不是交叉加入?有什么区别?你错过了jsonb_array_elements中的s
    • @HaoHao:如果shipping_lines 数组为空。在这种情况下,cross join lateral 将不返回任何行,并且将过滤掉原始行。
    • 所以第二个答案也是LEFT JOIN on True?
    【解决方案2】:

    嗯。将逻辑移至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
    

    【讨论】:

    • 哦,你错过了(
    • @HaoHao . . .谢谢。
    猜你喜欢
    • 1970-01-01
    • 2015-03-25
    • 1970-01-01
    • 1970-01-01
    • 2020-03-29
    • 2016-02-28
    • 2019-09-03
    • 1970-01-01
    • 2016-02-10
    相关资源
    最近更新 更多