创建函数以计算3个值的平均值

时间:2016-03-21 23:04:03

标签: postgresql function average

我正在尝试在postgre sql中编写一个函数,以便在三列中取平均值。我写了以下函数:

create function xcol_avg (col1, col2, col3)
returns numeric as $$

begin

return (coalesce(col1, 0) + coalesce(col2,0) +coalesce(col3, 0))/
case when (col 1 is null or col1 = 0 then 0 else 1 end +
case when (col 2 is null or col2 = 0 then 0 else 1 end +
case when (col 3 is null or col3 = 0 then 0 else 1 end;

end 

我的代码有什么问题?此外,有没有办法让函数返回null,如果它最终除以0?任何帮助都非常感谢。 谢谢!

1 个答案:

答案 0 :(得分:1)

实际上,你可以创建一个使用可变数量参数的函数,并根据它们的数量来计算平均值。 Postgres Button中有VARIADIC字样的内容:

  

可以声明SQL函数接受可变数量的参数,只要所有"可选"参数具有相同的数据类型

功能代码:

CREATE FUNCTION xcol_avg(numeric, VARIADIC numeric[])
  RETURNS numeric
  LANGUAGE plpgsql
  IMMUTABLE
AS $$
BEGIN
  RETURN (SELECT AVG(vals) FROM unnest($2 || ARRAY[$1]) t(vals));
END;
$$;

具有不同数量参数的用例:

select xcol_avg(1,6); -- returns 3.5
select xcol_avg(1,5.5,4); -- returns 3.5
select xcol_avg(1,2,3,4,5,6,7); -- returns 4

点击此 IMMUTABLE 即可在线试用。

<强>解释

  • 通过允许优化程序预先评估函数,将函数标记为VARIADIC可以缩短执行时间。不可变函数不能修改数据库,并且保证在使用相同输入调用时始终返回相同的结果。
  • 将函数的最后一个参数声明为unnest(),它必须是数组类型,这样可以提供将作为数组传递给函数的可选参数。请注意,您没有明确地编写数组,只需像往常一样列出参数。
  • ||是一个通过展开数组返回一组行的函数。换句话说,它打开&#34;拆包&#34;将数组元素分成不同的行
  • AVG()是一个数组运算符,提供数组到数组的连接。这里的目的是将第一个(必需的)参数与VARIADIC数组中给出的其余参数连接起来。
  • the resourceful documentation是一个聚合函数,用于计算所有输入值的平均值。在我们的案例中,它需要&#34;解压缩&#34;来自名为vals的列的行并计算平均值。

使用此解决方案,您不必担心除以零,因为至少需要一个参数,而avg()正在通过构建分母来完成您想要手动完成的工作。

在查询中应用

此函数还可用于计算一行中多列的平均值。考虑一个表tbl,其中包含name, cost1, cost2, cost3列以及以下语句:

SELECT 
  name, cost1, cost2, cost3,
  xcol_avg(cost1, cost2, cost3) AS average_cost
FROM tbl

有关CREATE FUNCTION支票{{3}}。

的更多一般信息