PostgreSQL中使用CASE表达式做GROUP BY提示聚合函数不允许错误如何解决
报错原因
- PostgreSQL执行SQL的优先级为
FROM/JOIN->WHERE->GROUP BY-> 聚合函数计算 ->SELECT->ORDER BY,你在SELECT中定义的seg别名,内部用到了聚合函数sum(a.payment),属于分组逻辑执行完成后才会计算的结果,不能反过来放在GROUP BY中作为分组依据,因此触发该报错。 - 额外问题:原SQL的
ORDER BY中使用了c.site字段,但zones临时表没有查询该字段,后续也会触发字段不存在的报错。
解决方案
采用两层查询结构:第一层先按region、月份维度做聚合计算,得到所有需要的聚合结果;第二层基于第一层的聚合结果生成seg字段,无需再次分组。
修改后的可运行SQL如下:
with zones as ( select school, region, dt -- 如果需要按site排序,在这里新增返回site字段 from district where dt between '1-jan-2021' and '31-jan-2021' ), base_agg as ( select c.region, to_char(a.dt, 'yyyy-mm') mth, sum(a.payment) total_payment, sum(a.records) records1, sum(a.amount) payment -- 如果需要按site排序,在这里新增返回c.site,同时加到下方GROUP BY中 from budget a left join zones c on a.school = c.school and a.dt = c.dt where a.dt between '1-jan-2021' and '31-jan-2021' group by c.region, to_char(a.dt, 'yyyy-mm') ) select region, mth, case when total_payment = 0 then '0' else '1' end as seg, records1, payment from base_agg order by -- 确认需要site排序的话,在这里加上site字段 region, mth, seg;
内容的提问来源于stack exchange,提问作者Rachad Gounou
相关产品推荐
相关产品推荐

