CREATE AGGREGATE name ( input_data_type [ , ... ] ) ( SFUNC = sfunc, STYPE = state_data_type [ , FINALFUNC = ffunc ] [ , INITCOND = initial_condition ] [ , SORTOP = sort_operator ] ) または以下の旧構文 CREATE AGGREGATE name ( BASETYPE = base_type, SFUNC = sfunc, STYPE = state_data_type [ , FINALFUNC = ffunc ] [ , INITCOND = initial_condition ] [ , SORTOP = sort_operator ] )
CREATE AGGREGATEは、新しい集約関数を定義します。 配布物には基本的、かつ、よく使用される集約関数がいくつか含まれています。これらの集約関数については、項9.18に文書化されています。 新しい型を定義する場合、またはまだ提供されていない集約関数が必要な場合、必要な機能を実現するためにCREATE AGGREGATEを使うことができます。
スキーマ名が付けられている場合(例えば、CREATE AGGREGATE myschema.myagg ...)、集約関数は指定されたスキーマで作成されます。 スキーマ名がなければ、集約関数は現在のスキーマで作成されます。
集約関数は名前と入力データ型(複数可)の組み合わせによって識別されます。 演算の対象となる入力データ型が異なっていれば、同じスキーマ内に同じ名前の集約関数があっても構いません。 1つのスキーマ内では、集約関数の名前と入力データ型(複数可)は、通常の関数の名前と入力データ型と異なる必要があります。
集約関数は1つか2つの通常の関数から作られます。 状態遷移関数sfuncと省略可能な最終計算関数ffuncです。 これらは以下のように使われます。
sfunc( 内部状態, 次のデータ値 ) ---> 次の内部状態 ffunc( 内部状態 ) ---> 集約の結果
PostgreSQLは、集約の現在の内部状態を保持するstypeデータ型の一時変数を作成します。 それぞれの入力行に対して、集約引数の値が計算され、現在の状態値と新しい引数値で新しい内部状態変数を計算するために状態遷移関数が呼び出されます。 全ての行が処理されると、集約の出力値を計算するために最終関数が1回呼び出されます。 最終関数がない場合は、終了時の状態値がそのまま返されます。
集約関数は、内部状態の初期値として初期状態を提供することができます。 これはtext型の値としてデータベースに格納されますが、状態値データ型の定数として有効な外部表現でなければいけません。 初期状態が与えられていない場合、状態値はNULLから始まります。
状態遷移関数が"厳格(strict)"と宣言されている場合、NULLを入力値にして呼び出すことはできません。
そのような遷移関数では、集約は次のように実行されます。
NULL入力値を持つ行は無視されます。
(関数は呼び出されず、前回の状態値が保持されます。)
初期状態値がNULLである場合、初めて入力行がすべて非NULL入力値であった時にその引数の値で状態値を置き換え、次に入力行がすべて非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インデックス演算子クラスの"より小さい"ストラテジか"より大きい"ストラテジのメンバでない限り、最適化が実際には効果がないことに注意してください。
作成する集約関数の名前です(スキーマ修飾名も可)。
集約関数が演算する入力データ型です。
引数が存在しない集約関数を作成するには、入力データ型のリストに*と記載してください
(例えば count(*)
などの集約です)。
CREATE AGGREGATEの旧構文では、入力データ型は集約名称の次に記載されたものではなくbasetypeパラメータにより指定されます。 この構文では1つの入力パラメータしか指定できないことに注意してください。 引数を持たない集約を定義するためには、basetypeを"ANY" (*ではありません)と指定してください。
それぞれの入力行に対して呼び出される状態遷移関数の名前です。 N引数を持つ集約関数では、sfuncはN+1個の引数を取らなければなりません。 最初の引数はstate_data_type型で、残りはその集約の入力データ型として宣言したものと一致していなければなりません。 この関数はstate_data_type型の値を返さなければなりません。 この関数は、現在の状態値と現在の入力データ値を受け取り、次の状態値を返します。
集約の状態値のデータ型です。
最終関数の名前です。最終関数は、全ての入力行に対する処理が終わった後、集約の結果を計算するために呼び出されます。 この関数はstate_data_type型の引数を1つ取らなければなりません。 集約の出力データ型はこの関数の返り値として定義されます。 ffuncが指定されない場合には、集約の結果として終了時の状態値が使われます。出力型はstate_data_typeになります。
状態値の初期設定です。 データ型state_data_typeとして受け取り可能な文字列定数でなければいけません。 このパラメータが指定されない場合、状態値はNULLから始まります。
MIN
またはMAX
のような集約に対して関連付いたソート演算子です。
これは単なる演算子の名前です(スキーマで修飾可能)。
この演算子は集約(これは単一引数の集約でなければなりません)と同じ入力データ型を持つと前提されています。
CREATE AGGREGATEのパラメータは、任意の順番で記述することができます。上記の順番で記述する必要はありません。