Postgres plperl - 创建平均可疑的聚合函数

时间:2016-07-12 05:36:20

标签: postgresql perl plperl

我正在尝试将所有dBm值作为日期并对其进行平均,但要平均dBm,需要将它们转换为瓦特,取平均值,然后转换回dBm。

以下是我尝试使用plperl的内容。

CREATE OR REPLACE FUNCTION avg_dbm(double precision[]) RETURNS integer AS $$

    my $watts = 0;
    my $watt_count = 0;

    foreach my $dbm ( @_ ) {
        $watts = $watts + ( 10 ** ( $dbm / 10 ) ) / 1000;
        $watt_count++;
    }

    my $avg_watts = $watts / $watt_count;
    my $avg_dbm  = 10 * log(  1000 * $avg_watts ) / log(10);

    return $avg_dbm;

$$ LANGUAGE plperl;

DROP AGGREGATE IF EXISTS db_agg( double precision );

CREATE AGGREGATE db_agg ( double precision ) ( 
    sfunc = array_append,
    stype = double precision[],
    finalfunc = avg_dbm
);


SELECT avg_db( dbm ) FROM data GROUP BY meas_date;

运行此函数时出现的错误是:

ERROR:  column "data.dbm" must appear in the GROUP BY clause or be used in an aggregate function

我认为我已经接近这个权利,但似乎无法弄明白。查询只需要按日期聚合,并将该日期的所有dbm值平均为一个值。

任何想法或解决方案?

编辑:更新了适当的perl变量名称的plsql代码

更新

我将SQL更改为:

SELECT db_agg( dbm ) FROM data GROUP BY meas_date;

并收到此错误:

ERROR:  Operation "/": no method found,
    left argument in overloaded package PostgreSQL::InServer::ARRAY,
    right argument has no overloaded magic at line 7.
CONTEXT:  PL/Perl function "avg_dbm"

有问题的部分是plperl中的这行代码

$watts = $watts + ( 10 ** ( $dbm / 10 ) ) / 1000;

特别是$ dbm不希望除以10 ...

我尝试更改函数以使用非数组双精度数据类型,但这似乎不起作用。我也尝试在MySQL中添加0,希望进行自动转换,但失败了。

在分区中使用它们之前是否需要对阵列数据类型进行一些处理?

1 个答案:

答案 0 :(得分:2)

尝试使用聚合,而不是函数:

SELECT db_agg(dbm) 
FROM data 
GROUP BY meas_date;

并不应该$avg_watts代替$decimal在函数体中?