2016-07-12 3 views
1

Ich versuche, alle dBm-Werte für ein Datum zu nehmen und sie zu mitteln, aber um dBm zu mitteln, müssen sie in Watt umgewandelt, gemittelt und dann wieder in dBm konvertiert werden.Postgres plperl - Aggregatfunktion zur Mittelwertbildung erstellen

Hier ist was ich mit plperl probiert habe.

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; 

Der Fehler, die ich bekomme, wenn diese Funktion ausgeführt ist:

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

Ich glaube, ich bin in der Nähe dieses Recht zu haben, aber kann nicht scheinen, um es herauszufinden. Die Abfrage muss nur nach Datum aggregieren und alle dbm-Werte für dieses Datum in einen Wert mitteln.

Irgendwelche Ideen oder Lösungen?

EDIT: aktualisiert plsql Code für die richtige perl Variablenname

UPDATE:

änderte ich die SQL:

SELECT db_agg(dbm) FROM data GROUP BY meas_date; 

Und diesen Fehler:

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" 

Der Teil, der Probleme hat, ist i n dieser Codezeile in plperl

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

Insbesondere $ dbm nicht durch 10 geteilt werden möchte ...

Ich habe versucht, die Funktionen von Nicht-Array mit doppelter Genauigkeit Datentypen zu verwenden, sondern dass didn Es scheint nicht zu funktionieren. Ich habe auch versucht, 0 hinzuzufügen, wie in MySQL in der Hoffnung, automatische Umwandlung zu machen, aber gescheitert.

Gibt es eine Behandlung von Array-Datentypen, bevor sie in der Division verwendet werden?

Antwort

2

Versuchen Sie, das Aggregat zu verwenden, nicht die Funktion:

SELECT db_agg(dbm) 
FROM data 
GROUP BY meas_date; 

Und nicht $avg_watts anstelle von $decimal im Funktionskörper enthalten sein sollte?

+0

Sie haben Recht, ich habe $ dezimal zu $ ​​avg_watts geändert .. – atom12

Verwandte Themen