如何合并返回复合类型列表的函数与汇总该列表的函数
PostgreSQL 合并数组提取与分组汇总的简洁实现
直接通过数组展开+分组聚合的原生写法,就能替代原有的两个函数,完全不需要临时表,无副作用,符合PostgreSQL的惯用处理方式。
假设你的Level复合类型结构类似:
CREATE TYPE Level AS (key text, value numeric);
原表为my_table,包含id int和levels Level[]字段。
方案1:直接查询(无需封装函数)
如果不需要复用逻辑,直接用这条SQL就能完成提取+分组汇总:
SELECT t.id, l.key, SUM(l.value) AS total_value FROM my_table t CROSS JOIN UNNEST(t.levels) l GROUP BY t.id, l.key;
方案2:封装为单个可复用函数
如果需要把逻辑封装成函数,创建一个返回表类型的稳定函数(无副作用):
CREATE OR REPLACE FUNCTION get_levels_with_sum() RETURNS TABLE ( record_id int, level_key text, total_value numeric ) AS $$ BEGIN RETURN QUERY SELECT t.id AS record_id, (l).key AS level_key, SUM((l).value) AS total_value FROM my_table t CROSS JOIN UNNEST(t.levels) l GROUP BY t.id, (l).key; END; $$ LANGUAGE plpgsql STABLE;
调用方式非常简单:
SELECT * FROM get_levels_with_sum();
核心逻辑说明
- 用
CROSS JOIN UNNEST(t.levels)直接展开数组字段,替代原get_levels的提取逻辑; - 通过
GROUP BY按复合类型的key分组,搭配内置SUM函数完成汇总,替代原get_levels_sum的功能; STABLE关键字标记函数为稳定型,保证它不会修改数据,完全符合你"无副作用"的要求;- 全程不需要临时表,比临时表方案更高效,也是PostgreSQL处理数组+分组统计的标准写法。
如果你的Level类型字段名不是key和value,只需要替换成实际的字段名称即可。
内容的提问来源于stack exchange,提问作者Edmund's Echo
相关产品推荐
相关产品推荐

