postgresql:参数化聚合类型?

postgresql:参数化聚合类型?,postgresql,aggregate-functions,plpgsql,Postgresql,Aggregate Functions,Plpgsql,我需要提供一些存储过程,这些存储过程返回在数据库中选择的值(即平均值、总和、最小值、最大值等)上运行聚合函数的结果。值的选择始终以类似的方式进行 我的第一个简单实现是,每个聚合函数类型包含一个存储过程,例如get_avg(…),get_sum(…)。这些函数显然共享大量重复代码。我想知道是否有办法将聚合类型移动到一个参数中,然后只使用一个存储过程,例如get_aggregate(aggr_type,…) 就pl/pgsql实现而言,我能想到的唯一方法是选择应该进入聚合的值,然后在aggr_typ

我需要提供一些存储过程,这些存储过程返回在数据库中选择的值(即平均值、总和、最小值、最大值等)上运行聚合函数的结果。值的选择始终以类似的方式进行

我的第一个简单实现是,每个聚合函数类型包含一个存储过程,例如get_avg(…),get_sum(…)。这些函数显然共享大量重复代码。我想知道是否有办法将聚合类型移动到一个参数中,然后只使用一个存储过程,例如get_aggregate(aggr_type,…)

就pl/pgsql实现而言,我能想到的唯一方法是选择应该进入聚合的值,然后在aggr_type==…/else子句,因为存在聚合类型。但这不是很灵活,需要在需要支持新聚合类型时更改代码

有没有办法在pl/pgsql中参数化函数名?
有人能想出一种我看不到的方法吗?

从技术上讲,您可以在plpgsql函数中使用
execute
语句:

return query
execute $x$
select id, $x$ || quote_ident(agg_func) || $x$(col)::numeric as agg
from bar
$x$;
(参见下面的适当示例)。问题是,这意味着在每次调用时都要分析/规划查询

有时,一个更好的选择是创建一个函数来创建各种需要的函数。大概是这样的:

create or replace function generate_agg_functions(_table regclass) returns void as $$
declare
  _agg_type text[] = '{sum, avg}';
  _ret_type regtype[] = '{numeric, numeric}';
  rec record;
begin
  for rec in select _agg_type[i] as agg_type, _ret_type[i] as ret_type
  from generate_subscripts(_agg_type, 1) i
  loop
  execute $x$
  create or replace function $x$ || quote_ident(_table || '_' || rec.agg_func) || $x$()
    returns table (id int, $x$ || quote_ident(rec.agg_type) || ' ' || ret_type || $x$)
  $def$
  begin
    return query
    select id,
           $x$ || quote_ident(rec.agg_type) || $x$(col)::$x$ || rec.ret_type || $x$
             as $x$ || quote_ident(rec.agg_type) || $x$
    from $x$ || _table || $x$;
  end;
  $def$ language plpgsql stable;
  $x$;
  end loop;
end;
$$ language plpgsql;

编写起来有点棘手,但最终不会在不影响单个聚合性能的情况下复制代码。

wow!我觉得现在关于postgresql我还有很多东西要学。如果aggr_type==…/否则就不是那么坏的选择了。谢谢你的帮助,伙计!:-)