CREATE AGGREGATE name ( BASETYPE = input_data_type, SFUNC = sfunc, STYPE = state_data_type [ , FINALFUNC = ffunc ] [ , INITCOND = initial_condition ] [ , SORTOP = sort_operator ] )
CREATE AGGREGATEは、新しい集約関数を定義します。 配布物には基本的、かつ、よく使用される集約関数がいくつか含まれています。これらの集約関数については、項9.15に文書化されています。 新しい型を定義する場合、またはまだ提供されていない集約関数が必要な場合、必要な機能を実現するためにCREATE AGGREGATEを使うことができます。
スキーマ名が付けられている場合(例えば、CREATE AGGREGATE myschema.myagg ...)、集約関数は指定されたスキーマで作成されます。 スキーマ名がなければ、集約関数は現在のスキーマで作成されます。
集約関数は名前と入力データ型の組み合わせによって識別されます。 演算の対象となる入力データ型が異なっていれば、同じスキーマ内に同じ名前の集約関数があっても構いません。 1つのスキーマ内では、集約関数の名前と入力データ型は、通常の関数の名前と入力データ型と異なる必要があります。
集約関数は1つか2つの通常の関数から作られます。 状態遷移関数sfuncと省略可能な最終計算関数ffuncです。 これらは以下のように使われます。
sfunc( 内部状態, 次のデータ項目 ) ---> 次の内部状態 ffunc( 内部状態 ) ---> 集約の結果
PostgreSQLは、集約の現在の内部状態を保持するstypeデータ型の一時変数を作成します。 それぞれの入力データ項目に対して、新しい内部状態値を計算するために状態遷移関数が呼び出されます。 全てのデータが処理されると、集約の出力値を計算するために最終関数が1回呼び出されます。 最終関数がない場合は、終了時の状態値がそのまま返されます。
集約関数は、内部状態の初期値として初期状態を提供することができます。 これはtext型の列としてデータベースに格納されますが、状態値データ型の定数として有効な外部表現でなければいけません。 初期状態が与えられていない場合、状態値はNULLから始まります。
状態遷移関数が"厳格(strict)"と宣言されている場合、NULLを入力値にして呼び出すことはできません。
そのような遷移関数では、集約は次のように実行されます。
NULL入力値は無視されます(関数は呼び出されず、以前の状態値を保持します)。
初期状態値がNULLである場合、最初の非NULL入力値が状態値を置き換え、2番目の非NULL入力値から遷移関数の呼び出しが始まります。
このような動作は、max
のような集約を実装するには便利です。
ただし、state_data_typeがinput_data_typeと同じ時にのみ有効であることに注意してください。
これらの型が異なる時は、非NULL初期値を供給するか、厳格でない遷移関数を使わなければいけません。
状態遷移関数が厳格(strict)でない場合は、それぞれの入力値に対してその関数が無条件に呼び出されるので、NULL入力とNULL遷移値を自分で処理しなければいけません。 これは、関数の作成者が、集約関数におけるNULL値の扱いを完全に制御できることを意味します。
最終関数が"厳格(strict)"と宣言されていると、終了状態値がNULLの時は、最終関数が呼び出されません。
その場合、NULLという結果が自動的に出力されます
(もちろんこれは、厳格な関数の一般的な動作に過ぎません)。
どのような場合でも、最終関数はNULLを返すことができます。
例えば、avg
の最終関数は、入力が0行だとわかるとNULLを返します。
MIN
やMAX
のような振舞いをする集約では、すべての入力行を走査せずにインデックスを検索することで最適化できることがあります。
このように最適化される集約の場合、ソート演算子を指定することで明示してください。
その演算子で生成されるソート順で集約の最初の要素が生成されなければならないということが基本的な必要条件です。
言い換えると、
SELECT agg(col) FROM tab;
が
SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
と同じでなければならないということです。
更に、集約がNULL入力を無視すること、および、NULL以外の入力がまったくなかった時にのみNULLという結果を返すことも前提となります。
通常、データ型の<演算子はMIN
のソート演算子として、また、>演算子はMAX
のソート演算子として適切です。
指定した演算子がB-treeインデックス演算子クラスの"より小さい"ストラテジか"より大きい"ストラテジのメンバでない限り、最適化が実際には効果がないことに注意してください。
作成する集約関数の名前です(スキーマ修飾名も可)。
集約関数が演算する入力データ型です。
入力値を検査しない集約には、"ANY"と指定します
(例えば count(*)
)。
それぞれの入力データ値に対して呼び出される状態遷移関数の名前です。 通常は2つの引数を持ちます。最初の引数はstate_data_type型で、2番目はinput_data_type型です。 入力値を検査しない集約では、state_data_type型の引数を1つだけ取ります。 どちらの場合でも、state_data_type型の値を返さなければなりません。 この関数は、現在の状態値と現在の入力データ項目を受け取り、次の状態値を返します。
集約の状態値のデータ型です。
最終関数の名前です。最終関数は、全ての入力データに対する処理が終わった後、集約の結果を計算するために呼び出されます。 この関数はstate_data_type型の引数を1つ取らなければなりません。 集約の出力データ型はこの関数の返り値として定義されます。 ffuncが指定されない場合には、集約の結果として終了時の状態値が使われます。出力型はstate_data_typeになります。
状態値の初期設定です。 データ型state_data_typeとして受け取り可能な文字列定数でなければいけません。 このパラメータが指定されない場合、状態値はNULLから始まります。
MIN
またはMAX
のような集約に対して関連付いたソート演算子です。
これは単なる演算子の名前です(スキーマで修飾可能)。
この演算子は集約と同じ入力データ型を持つと前提されています。
CREATE AGGREGATEのパラメータは、任意の順番で記述することができます。上記の順番で記述する必要はありません。