3

sum()関数の代わりに使用するために、PostgreSQL で新しい集計関数を作成しようとしています。

ここでマニュアルの旅を始めました。

倍精度値の配列を取り、それらを合計してから追加の計算を行う関数を作成したかったので、最初にその最終関数を作成しました。

takes double precision as input and gives double precision as output    
DECLARE
      v double precision;
BEGIN
      IF tax > 256 THEN
            v := 256;
      ELSE
            v := tax;
      END IF;
      RETURN v*0.21/0.79;
END;

次に、倍精度値の配列を取り、前の関数が処理する単一の倍精度値を出力する集計関数を作成したいと考えました。

CREATE AGGREGATE aggregate_ee_income_tax (float8[]) (
  sfunc = array_agg
 ,stype = float8
 ,initcond = '{}'
 ,finalfunc = eeincometax);

そのコマンドを実行すると得られるものは次のとおりです。

エラー: 関数 array_agg(double precision, double precision[]) は存在しません

マニュアルにはarray_agg()が既存の関数としてリストされているため、ここで行き詰まっています。私は何を間違っていますか?

また、実行すると:

\da
                     List of aggregate functions
 Schema | Name | Result data type | Argument data types | Description 
--------+------+------------------+---------------------+-------------
(0 rows)

私のインストールには集計関数がまったくありませんか? または、ユーザー定義関数のみをリストしますか?

基本的に私が理解しようとしていること:

1) 既存の関数を使用して配列値を合計できますか?

2) 関数の入力データ型と出力データ型を調べるにはどうすればよいですか? array_agg()あらゆる種類の入力を受け取るDocs クレーム。

3) 独自の集計関数の何が問題になっていますか?

編集 1

私が達成しようとしていることのより多くの情報とより明確なイメージを与えるために:

次のようないくつかのテーブルに対する1つの巨大なクエリがあります。

SELECT sum(tax) ... from (SUBQUERY) as foo group by id

その合計関数を独自の集計関数に置き換えたいので、バックエンドで追加の計算を行う必要はありません。それらはすべてデータベース レベルで実行できるためです。

編集 2

アリの答えを受け入れました。最終的な解決策はコメントから得られるため、参照用にここに投稿します。

CREATE AGGREGATE aggregate_ee_income_tax (float8)
(
 sfunc = float8pl
,stype = float8
,initcond = '0.0'
,finalfunc = eeincometax
);
4

2 に答える 2

3

@Antsの優れたアドバイスに加えて:

1.)最終的な関数は次のように簡略化できます。

CREATE FUNCTION eeincometax(float8)
  RETURNS float8 LANGUAGE SQL AS
$func$
SELECT (least($1, 256) * 21) / 79
$func$;

2.)あなたはお金を扱っているようですか?この場合、タイプnumeric(推奨)またはmoney目的に使用することを強くお勧めします。浮動小数点演算は、多くの場合、十分に正確ではありません。

3.)アグリゲートの初期条件は、単純に次のようになります0

CREATE AGGREGATE aggregate_ee_income_tax(float8)
(
  sfunc     = float8pl
 ,stype     = float8
 ,initcond  = 0
 ,finalfunc = eeincometax
);

4.)あなたの場合(least(sum(tax), 256) * 21) / 79、おそらくカスタムアグリゲートよりも高速です。PostgreSQLが提供する集計関数は、Cで記述されており、パフォーマンスが最適化されています。代わりにそれを使用します。

于 2012-09-14T19:37:23.690 に答える
3

配列 agg は通常の関数ではなく集約関数であるため、新しい集約の状態遷移関数として使用することはできません。やりたいことは、array_agg と同じ状態遷移関数とカスタムの最終関数を持つ集約関数を作成することです。

残念ながら、array_agg の状態遷移関数は内部データ型に関して定義されているため、再利用できません。幸いなことに、コアには既に必要なことを実行する既存の関数があります。

CREATE AGGREGATE aggregate_ee_income_tax (float8)(
    sfunc = array_append,
    stype = float8[],
    initcond = '{}',
    finalfunc = eeincometax);

また、型が混同されていることに注意してください。おそらく、配列のセットをフロートに集約するのではなく、フロートのセットを配列に集約する必要があります。

于 2012-09-13T08:31:50.977 に答える