2

Postgresでカスタム集計関数を実装しようとしています。これは、方向を度単位で平均化します。つまり、次のことができるようになります。

SELECT circavg(direction) FROM sometable;

これは、次の式を使用して実行できます。

xbar = atan2(sum(sin(xi), sum(cos(xi)))

sfunc方向性をとるanを定義し、その正弦と余弦を2つのアキュムレータに追加する必要があると思います。次に、最後の関数は、atan2を使用して2つのコンポーネントをある方向に変換し直します。

sfunc現在の状態が2つのコンポーネントで構成されるようにを定義する方法を理解できません(float, float)。ドキュメントは具体的な例が少し短いので、助けていただければ幸いです。

4

2 に答える 2

4

内部でARRAY型を利用できます。引数の型は、引き続き任意の数値型にすることができます。float(= )で示すdouble precision

CREATE OR REPLACE FUNCTION f_circavg (float[], float)
  RETURNS float[] LANGUAGE sql STRICT AS
'SELECT ARRAY[$1[1] + sin($2), $1[2] + cos($2), 1]';

CREATE OR REPLACE FUNCTION f_circavg_final (float[])
  RETURNS float  LANGUAGE sql AS
'SELECT CASE WHEN $1[3] > 0 THEN atan2($1[1], $1[2]) END';

CREATE AGGREGATE circavg (float) (
   sfunc     = f_circavg
 , stype     = float[]
 , finalfunc = f_circavg_final
 , initcond  = '{0,0,0}'
);

遷移関数f_circavg()が定義されSTRICTているため、入力のある行は無視されNULLます。また、3番目の配列要素を設定して、1つ以上の入力行を持つセットを識別します。それ以外の場合CASE、final関数はを返しますNULL

テスト用の一時的なテーブル:

CREATE TEMP TABLE t (x float);
INSERT INTO t VALUES (2), (NULL), (3), (4), (5);

私は魔法NULLをテストするために値を投入しました。STRICT電話:

SELECT circavg(x) FROM t;

       circavg
-------------------
 -2.78318530717959

クロスチェック:

SELECT atan2(sum(sin(x)), sum(cos(x))) FROM t;

       atan2
-------------------
 -2.78318530717959

同じを返します。動作しているようです。より大きなテーブルを使用したテストでは、通常の集計関数を使用した最後の式は、カスタム集計よりも4倍高速でした。

ゼロ入力行/NULL入力のみをテストします。

SELECT circavg(x) FROM t WHERE false;     -- no input rows
SELECT circavg(x) FROM t WHERE x IS NULL; -- only NULL input

NULLどちらの場合も戻ります。

于 2012-04-19T10:29:56.120 に答える
0

PostgreSQL provides you with a set of geometry types, POINT being the fundamental one.
Use this type as the input parameter for your function.

You can create your custom type as an alternative if you prefer.

于 2012-04-19T10:02:36.737 に答える