分析関数と集約関数はどちらも、行セット(一連の行の集合)に対して集計計算を行います。違いは、集約関数が各グループごとに1つの値(1行)しか返せないのに対し、分析関数は各グループごとに複数の値(複数行)を返せる点です。この行のグループはウィンドウ(Window)と呼ばれ、analytic_clauseで定義します。ウィンドウのサイズは実際の行数または論理的な間隔(例えば時間)によって決まり、グループ内の各行はウィンドウに基づく論理的な計算結果です。
分析関数をトリガーするには、ウィンドウを指定するための特殊なキーワード OVER が必要です。ウィンドウには以下の3つの部分が含まれます:
パーティショニング規範:入力行を異なるパーティションに分割するために使用されます。このプロセスは
GROUP BY句による分割プロセスと類似しています。ソート規範:分析関数内での入力データ行の実行順序を決定するために使用されます。
ウィンドウ境界:データを計算するウィンドウの境界を指定します。デフォルト値は
RANGE UNBOUNDED PRECEDINGです。この境界は、現在のパーティションの開始から現在の行までのすべてのデータを含みます。
分析関数は、クエリ内で最後に実行される操作のセットです(最後の ORDER BY 句を除く)。分析関数を処理する前に、すべての JOIN および WHERE、GROUP BY、HAVING 句を完了している必要があります。そのため、分析関数は選択リストまたは ORDER BY 句にのみ記述できます。
構文
analytic_function
analytic_function は分析関数の名前を指定します。構文は以下のとおりです:
analytic_function([ arguments ]) OVER (analytic_clause)
分析関数は0〜3つの arguments 引数を使用します。引数は任意の数値データ型、または暗黙的に数値データ型へ変換可能な任意の非数値データ型にすることができます。OceanBaseはデータ型の優先順位に基づいて最も高い数値優先順位を持つ引数を特定し、残りの引数をこの最も高い数値優先順位を持つ引数のデータ型へ暗黙的に変換します。戻り値の型も、個々の関数で特に指定されていない限り、最も高い数値優先順位を持つ引数のデータ型となります。
analytic_clause
分析句(analytic_clause)は、OVER analytic_clause を使用して、関数がクエリ結果セット上で操作を実行することを指示します。この句は FROM、WHERE、GROUP BY、HAVING 句の後に評価されます。選択リストや ORDER BY 句でこの句を使用して分析関数を指定できます。分析関数に基づくクエリ結果をフィルタリングする場合は、これらの関数を親クエリ内にネストし、ネストされたサブクエリの結果をフィルタリングします。構文は以下のとおりです:
[ query_partition_clause ] [ order_by_clause [ windowing_clause ] ]
注意
- 分析句内で分析関数を指定することで、分析関数をネストすることはできません。しかし、サブクエリ内で分析関数を指定し、その上で別の分析関数を計算することはできます。
analytic_clauseには、ユーザー定義の解析関数および組み込みの解析関数を指定できます。
query_partition_clause
パーティション句(query_partition_clause)は、PARTITION BY 句を使用して、クエリ結果セットを1つまたは複数の value_expr に基づくグループに分割します。この句を省略した場合、関数はクエリ結果セットのすべての行を単一のグループと見なします。
同一クエリ内で複数の分析関数を指定でき、各関数はキーによって同じまたは異なるパーティションを持ちます。query_partition_clause で分析関数を指定し、かつクエリ対象が並列属性を持つ場合、関数の計算も並列化されます。
value_expr の有効な値は、定数、列、非分析関数、関数式、またはそれらのいずれかを含む式です。
構文は以下のとおりです:
PARTITION BY { expr[, expr ]... | ( expr[, expr ]... ) }
order_by_clause
ソート句 order_by_clause を使用して、パーティション内でデータをソートする方法を指定します。すべての分析関数において、複数のキーに基づいてパーティション内の値をソートできます。各キーは value_expr で定義され、ソート順序で制限されます。
各関数では、複数のソート式を指定できます。値をソートする関数を使用する場合、これが特に有効です。
order_by_clause が複数の行に対して同じ値を返す場合、関数の動作は以下のとおりです:
CUME_DIST、DENSE_RANK、NTILE、PERCENT_RANK、およびRANKは各行に対して同じ結果を返します。ROW_NUMBERは、order_by_clauseに基づく値があっても、各行に対して一意の値を割り当てます。この値は行の処理順序に基づきますが、ORDER BYで全体的なソートが実現できない場合、その順序は不確定になる可能性があります。その他の分析関数の結果は、ウィンドウルールに依存します。
RANGEキーワードを使用した論理ウィンドウを指定した場合、関数は各行に対して同じ結果を返します。ROWSキーワードで物理ウィンドウを指定した場合、結果は不確定になります。
構文は以下のとおりです:
ORDER [ SIBLINGS ] BY{ expr | position | c_alias } [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ] [, { expr | position | c_alias } [ ASC | DESC ][ NULLS FIRST | NULLS LAST ]]...
ASCまたはDESCキーワード
ソート順序を指定します。ASC は昇順、DESC は降順を表します。デフォルトは昇順(ASC)です。
NULLS FIRSTまたはNULLS LASTキーワード
order_by_clause の nulls first と nulls last について説明します。nulls first はソート時に NULL 値を最小値として扱うことを意味し、nulls last はソート時に NULL 値を最大値として扱うことを意味します。
ORDER BY句の制限
ORDER BY 句の使用には、以下の制限があります:
分析関数では、
order_by_clauseには必ず式(expr)を使用する必要があります。SIBLINGSキーワードは無効です(階層クエリでのみ関連します)。位置(position)と列エイリアス(c_alias)も無効です。それ以外の場合、このorder_by_clauseは、クエリ全体またはサブクエリのソートコマンドと同じになります。RANGEキーワードを使用した分析関数は、その関数のORDER BY句で複数のソートキーを使用できます。以下のウィンドウを指定する必要があります:RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW(略称RANGE UNBOUNDED PRECEDING)RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWINGRANGE BETWEEN CURRENT ROW AND CURRENT ROWRANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
上記の4つのウィンドウ以外では、分析関数の ORDER BY 句内のウィンドウ境界には、1つのソートキーしか指定できません。この制限は、ROW キーワードで指定されたウィンドウ境界には適用されません。
windowing_clause
一部の分析関数では windowing_clause を使用できます。構文は次のとおりです:
{ ROWS | RANGE } { BETWEEN { UNBOUNDED PRECEDING | CURRENT ROW | value_expr { PRECEDING | FOLLOWING } } AND{ UNBOUNDED FOLLOWING | CURRENT ROW | value_expr { PRECEDING | FOLLOWING } } | { UNBOUNDED PRECEDING | CURRENT ROW| value_expr PRECEDING}}
ROWS または RANGE キーワード
これらのキーワードは、各行に対して関数結果を計算するためのウィンドウを定義し、その後その関数をウィンドウ内のすべての行に適用します。ウィンドウはクエリの結果セットまたはパーティションを上から下へと移動します。ウィンドウは FRAME とも呼ばれ、OceanBase データベースは以下のウィンドウステートメントをサポートしています:
ROWS:物理単位(行)でウィンドウを指定します。RANGE:ウィンドウを論理オフセットとして指定します。デフォルトはRANGE UNBOUNDED PRECEDINGです。
分析関数で windowing_clause を使用する場合は、order_by_clause を追加する必要があります。windowing_clause が RANGE 句でウィンドウの境界を定義している場合、order_by_clause では1つの式のみを指定できます。詳細については、ORDER BY 句の制限 を参照してください。
論理オフセットを持つ分析関数が返す値は常に決定的です。しかし、物理オフセットを持つ分析関数が返す値は不確定な結果を生じる可能性があります。物理オフセットを持つ分析関数が決定的な値を返すためには、ソート式が一意のソートを返す必要があります。そのため、order_by_clause では複数の列を指定して一意のソートを実現する必要があります。
BETWEEN ... AND キーワード
BETWEEN ... AND 句を使用して、ウィンドウの開始点と終了点を指定します。最初の式(AND の前)が開始点を定義し、2番目の式(AND の後)が終了点を定義します。BETWEEN を省略して終了点のみを指定した場合、OceanBase データベースはそれを開始点と見なし、終了点はデフォルトで現在行になります。
UNBOUNDED PRECEDING キーワード
UNBOUNDED PRECEDING は、ウィンドウがパーティションの最初の行から始まることを示します。これは開始点に使用できますが、終了点には使用できません。
UNBOUNDED FOLLOWING キーワード
UNBOUNDED FOLLOWING は、ウィンドウがパーティションの最後の行で終わることを示します。これは終了点に使用できますが、開始点には使用できません。
CURRENT ROW キーワード
開始点として、CURRENT ROW はウィンドウが現在行または現在値から始まることを指定します(ROW か RANGE が指定されているかどうかによって異なります)。この場合、終点は value_expr PRECEDING にすることはできません。終了点として、CURRENT ROW はウィンドウが現在行または値で終わることを指定します(ROW または RANGE を指定したかどうかによって異なります)。この場合、開始点は value_expr FOLLOWING にすることはできません。
value_expr PRECEDING または value_expr FOLLOWING キーワード
value_expr FOLLOWINGが開始点の場合、終了点はvalue_expr FOLLOWINGでなければなりません。value_expr PRECEDINGが終了点の場合、開始点はvalue_expr PRECEDINGでなければなりません。
時間間隔で定義された数値形式の論理ウィンドウを定義する場合は、変換関数を使用する必要がある場合があります。
ROWS を指定する場合:
value_exprは物理オフセットです。それは定数または式でなければならず、正の数として評価されなければなりません。value_exprが開始点の一部である場合、開始点と終了点の前の部分を1行として計算する必要があります。
RANGE を指定する場合:
value_exprは論理オフセットです。それは定数または式でなければならず、結果が正の数値または間隔リテラルである必要があります。order_by_clauseでは1つの式のみを指定できます。value_exprが数値の場合、ORDER BY exprは数値またはDATEデータ型でなければなりません。value_exprが間隔値の場合、ORDER BY exprはDATEデータ型でなければなりません。windowing_clauseを完全に省略した場合、デフォルト値はRANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROWです。