【问题标题】:Create function to compute an average of 3 values创建函数以计算 3 个值的平均值
【发布时间】:2016-03-21 23:04:03
【问题描述】:

我正在尝试在 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 

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

【问题讨论】:

标签: postgresql function average


【解决方案1】:

实际上,您可以创建一个函数,该函数将使用可变数量的参数,并根据它们的数量计算平均值。在Postgres 中有一个词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

点击此Button在线试用。

说明:

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

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

在查询中应用它:

此函数也适用于计算一行中多列的平均值。考虑一个表 tbl 与列 name, cost1, cost2, cost3 和下面的语句:

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

有关CREATE FUNCTION 的更多一般信息,请查看the resourceful documentation

【讨论】:

    猜你喜欢
    • 2017-09-26
    • 2021-02-14
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 2017-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多