集約関数のコンビネーター
集約関数の名前には、接尾辞を付けることができます。これにより、その集約関数の挙動が変化します。
-If
サフィックス -If は、任意の集約関数名に付与できます。この場合、集約関数は追加の引数として条件(UInt8 型)を受け取ります。集約関数は、その条件が真となる行だけを処理します。条件が一度も真とならなかった場合、デフォルト値(通常はゼロまたは空文字列)を返します。
例: sumIf(column, cond), countIf(cond), avgIf(x, cond), quantilesTimingIf(level1, level2)(x, cond), argMinIf(arg, val, cond) など。
条件付き集約関数を使用すると、サブクエリや JOIN を使わずに、複数の条件に対する集約値を同時に計算できます。たとえば、条件付き集約関数を用いてセグメント比較機能を実装できます。
-Array
-Array サフィックスは、任意の集約関数に付加できます。この場合、集約関数は引数として型 'T' ではなく、型 'Array(T)'(配列)を取ります。集約関数が複数の引数を受け取る場合、これらの引数はすべて長さが等しい配列でなければなりません。配列を処理する際、集約関数は、すべての配列要素に対して元の集約関数と同様に動作します。
例 1: sumArray(arr) - すべての 'arr' 配列に含まれるすべての要素を合計します。この例では、より単純に sum(arraySum(arr)) と書くこともできます。
例 2: uniqArray(arr) – すべての 'arr' 配列に含まれる一意な要素の数を数えます。これは、より簡単な方法として uniq(arrayJoin(arr)) でも実行できますが、常にクエリに 'arrayJoin' を追加できるとは限りません。
-If と -Array は組み合わせて使用できます。ただし、'Array' を先に、次に 'If' を付ける必要があります。例: uniqArrayIf(arr, cond), quantilesTimingArrayIf(level1, level2)(arr, cond)。この順序により、'cond' 引数は配列型の引数にはなりません。
-Map
-Map サフィックスは、任意の集約関数に付加して使用できます。これにより、引数として Map 型を受け取り、指定した集約関数を用いてマップ内の各キーに対応する値を個別に集約する集約関数が作成されます。結果も Map 型となります。
例
-SimpleState
このコンビネータを適用すると、集約関数は同じ値を返しますが、型が異なるようになります。これは、テーブルに保存して AggregatingMergeTree テーブルで使用できる SimpleAggregateFunction(...) 型です。
構文
引数
x— 集約関数のパラメータ。
戻り値
SimpleAggregateFunction(...) 型の集約関数の値。
例
クエリ:
結果:
-State
このコンビネータを適用すると、集約関数は結果の値(uniq 関数における一意な値の個数など)ではなく、集約の中間状態(uniq では、一意な値の数を計算するためのハッシュテーブル)を返します。これは AggregateFunction(...) 型であり、さらなる処理に利用したり、テーブルに保存して後から集約処理を完了させたりできます。
同一のデータに対しても、-MapState は中間状態におけるデータの順序が変化しうるため不変ではないことに注意してください。ただし、これはこのデータのインジェストには影響しません。
これらの状態を扱うには、次を使用します。
- AggregatingMergeTree テーブルエンジン
- finalizeAggregation 関数
- runningAccumulate 関数
- -Merge コンビネータ
- -MergeState コンビネータ
-Merge
このコンビネータを適用すると、集約関数は引数として中間集約状態を受け取り、それらを結合して集約を完了し、その結果の値を返します。
-MergeState
-Merge コンビネータと同様に中間集約状態をマージします。ただし、結果の値は返さず、-State コンビネータと同様に中間集約状態を返します。
-ForEach
テーブルに対する集約関数を、対応する配列要素ごとに集約を行い、その結果を配列で返す配列向けの集約関数に変換します。たとえば、配列 [1, 2]、[3, 4, 5]、[6, 7] に対する sumForEach は、対応する配列要素を加算した結果として [10, 13, 5] を返します。
-Distinct
引数の一意な組み合わせごとに、集約は 1 回だけ行われます。重複する値は無視されます。
例: sum(DISTINCT x)(または sumDistinct(x))、groupArray(DISTINCT x)(または groupArrayDistinct(x))、corrStable(DISTINCT x, y)(または corrStableDistinct(x, y))など。
-OrDefault
集約関数の動作を変更します。
集約関数に入力値がまったくない場合、このコンビネータを使用すると、その戻り値のデータ型に対するデフォルト値を返します。空の入力データを取り得る集約関数に適用できます。
-OrDefault は他のコンビネータと併用できます。
構文
引数
x— 集約関数のパラメータ。
戻り値
集約する対象が何もない場合、集約関数の戻り値の型に対するデフォルト値を返します。
型は使用する集約関数に依存します。
例
クエリ:
結果:
また -OrDefault は他のコンビネータと組み合わせて使用できます。これは、集約関数が空の入力を受け付けない場合に有用です。
クエリ:
結果:
-OrNull
集約関数の動作を変更します。
このコンビネータは、集約関数の結果を Nullable データ型に変換します。集約関数に集計対象の値が存在しない場合は、NULL を返します。
-OrNull は他のコンビネータと組み合わせて使用できます。
構文
引数
x— 集約関数のパラメーター。
戻り値
- 集約関数の結果を
Nullableデータ型に変換した値。 - 集約対象の値が存在しない場合は
NULL。
型: Nullable(集約関数の戻り値の型)。
例
集約関数名の末尾に -orNull を追加します。
クエリ:
結果:
-OrNull は他のコンビネータと組み合わせて使用することもできます。これは、集約関数が空の入力を許容しない場合に有用です。
クエリ:
結果:
-Resample
データをグループに分割し、その各グループ内で個別にデータを集計できるようにします。グループは、1 列の値を区間ごとに分割することで作成されます。
引数
start—resampling_keyの値に対する対象となる全区間の開始値。stop—resampling_keyの値に対する対象となる全区間の終了値。この全区間にはstopの値は含まれず、[start, stop)となります。step— 全区間をサブ区間に分割する際のステップ幅。aggFunctionはそれぞれのサブ区間ごとに独立して実行されます。resampling_key— データを区間に分割するために使用される値を持つカラム。aggFunction_params—aggFunctionのパラメータ。
戻り値
- 各サブ区間に対する
aggFunctionの結果の配列。
例
次のデータを持つ people テーブルを想定します。
[30,60) および [60,75) の区間に年齢が含まれる人の名前を取得しましょう。年齢は整数で表現しているため、実際には [30, 59] および [60,74] の区間の年齢が対象になります。
名前を配列に集約するには、集約関数 groupArray を使用します。この関数は 1 つの引数を取ります。ここでは name 列を渡します。groupArrayResample 関数では、age 列を使用して年齢ごとに名前を集約します。必要な区間を定義するために、groupArrayResample 関数には引数として 30, 75, 30 を渡します。
結果を確認します。
John は年齢が若すぎるため、サンプルには含まれていません。他の人たちは、指定した年齢区間に従って分布しています。
次に、指定した年齢区間ごとに、総人数と平均賃金を求めましょう。
-ArgMin
接尾辞 -ArgMin は、任意の集約関数の名前に付加できます。この場合、その集約関数は追加の引数を 1 つ受け取り、この引数には任意の比較可能な式を指定できます。集約関数は、指定された追加の式が最小値となる行だけを処理します。
例: sumArgMin(column, expr), countArgMin(expr), avgArgMin(x, expr) など。
-ArgMax
サフィックス -ArgMin と同様ですが、指定された追加の式に対して最大値を持つ行だけを処理します。