1

日付のすべての 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 値を 1 つの値に平均化するだけで済みます。

アイデアや解決策はありますか?

編集: 適切な 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 を追加しようとしましたが、失敗しました。

除算で使用する前に、配列データ型に必要な処理はありますか?

4

1 に答える 1