> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-mintlify-8a08bda2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> パラメトリック集約関数のドキュメント

# パラメトリック集約関数

一部の集約関数は、引数のカラム (圧縮に使用) だけでなく、初期化用の定数である一連のパラメータも受け取ることができます。構文では、括弧を1組ではなく2組使用します。最初の組はパラメータ用、2番目の組は引数用です。

<div id="histogram">
  ## histogram
</div>

適応型ヒストグラムを計算します。厳密な結果は保証されません。

```sql theme={null}
histogram(number_of_bins)(values)
```

この関数は [A Streaming Parallel Decision Tree Algorithm](http://jmlr.org/papers/volume11/ben-haim10a/ben-haim10a.pdf) を使用します。ヒストグラムのビンの境界は、新しいデータが関数に入力されるたびに調整されます。通常、ビンの幅は均一ではありません。

**引数**

`values` — 入力値を返す [式](/ja/reference/syntax#expressions)。

**パラメータ**

`number_of_bins` — ヒストグラムのビン数の上限。関数はビン数を自動的に計算します。指定したビン数に達するよう試みますが、できない場合はそれより少ないビン数を使用します。

**戻り値**

* 次の形式の [Tuples](/ja/reference/data-types/tuple) の [Array](/ja/reference/data-types/array):

  ```
  [(lower_1, upper_1, height_1), ... (lower_N, upper_N, height_N)]
  ```

  * `lower` — ビンの下限。
  * `upper` — ビンの上限。
  * `height` — 計算されたビンの高さ。

**例**

```sql theme={null}
SELECT histogram(5)(number + 1)
FROM (
    SELECT *
    FROM system.numbers
    LIMIT 20
)
```

```text theme={null}
┌─histogram(5)(plus(number, 1))───────────────────────────────────────────┐
│ [(1,4.5,4),(4.5,8.5,4),(8.5,12.75,4.125),(12.75,17,4.625),(17,20,3.25)] │
└─────────────────────────────────────────────────────────────────────────┘
```

たとえば、[bar](/ja/reference/functions/regular-functions/other-functions#bar) 関数を使ってヒストグラムを可視化できます。

```sql theme={null}
WITH histogram(5)(rand() % 100) AS hist
SELECT
    arrayJoin(hist).3 AS height,
    bar(height, 0, 6, 5) AS bar
FROM
(
    SELECT *
    FROM system.numbers
    LIMIT 20
)
```

```text theme={null}
┌─height─┬─bar───┐
│  2.125 │ █▋    │
│   3.25 │ ██▌   │
│  5.625 │ ████▏ │
│  5.625 │ ████▏ │
│  3.375 │ ██▌   │
└────────┴───────┘
```

この場合、ヒストグラムのビン境界は分からないことに注意してください。

<div id="sequencematch">
  ## sequenceMatch
</div>

数列に、パターンに一致するイベントチェーンが含まれているかを判定します。

**構文**

```sql theme={null}
sequenceMatch(pattern)(timestamp, cond1, cond2, ...)
```

<Note>
  同じ秒に発生したイベントは、数列内での順序が未定義になる場合があり、その結果に影響することがあります。
</Note>

**Arguments**

* `timestamp` — 時刻データを含むと見なされるカラムです。一般的なデータ型は `Date` と `DateTime` です。また、サポートされている [UInt](/ja/reference/data-types/int-uint) データ型も使用できます。

* `cond1`, `cond2` — イベントチェーンを記述する条件です。データ型: `UInt8`。条件引数は最大 32 個まで渡せます。この関数は、これらの条件で記述されたイベントのみを対象にします。数列に条件で記述されていないデータが含まれている場合、関数はそれらをスキップします。

**Parameters**

* `pattern` — パターン文字列です。[パターン構文](#pattern-syntax) を参照してください。

**Returned values**

* パターンに一致した場合は 1。
* パターンに一致しなかった場合は 0。

型: `UInt8`。

<div id="pattern-syntax">
  #### パターン構文
</div>

* `(?N)` — 位置 `N` の条件引数に一致します。条件には `[1, 32]` の範囲で番号が振られます。たとえば、`(?1)` は `cond1` パラメータに渡された引数に一致します。

* `.*` — 任意の数のイベントに一致します。パターンのこの要素に一致させるための条件引数は必要ありません。

* `(?t operator value)` — 2 つのイベントの間隔を秒単位で指定します。たとえば、パターン `(?1)(?t>1800)(?2)` は、発生時刻の差が 1800 秒を超えるイベントに一致します。これらのイベントの間には、任意の数の任意のイベントを挟めます。`>=`、`>`、`<`、`<=`、`==` の演算子を使用できます。

**例**

`t` テーブル内のデータについて考えます。

```text theme={null}
┌─time─┬─number─┐
│    1 │      1 │
│    2 │      3 │
│    3 │      2 │
└──────┴────────┘
```

次のクエリを実行します。

```sql theme={null}
SELECT sequenceMatch('(?1)(?2)')(time, number = 1, number = 2) FROM t
```

```text theme={null}
┌─sequenceMatch('(?1)(?2)')(time, equals(number, 1), equals(number, 2))─┐
│                                                                     1 │
└───────────────────────────────────────────────────────────────────────┘
```

この関数は、2 が 1 に続くイベントチェーンを検出しました。両者の間にある 3 はイベントとして定義されていないため、無視されました。例で示したイベントチェーンを検索する際にこの数値も考慮するには、それに対応する条件を追加する必要があります。

```sql theme={null}
SELECT sequenceMatch('(?1)(?2)')(time, number = 1, number = 2, number = 3) FROM t
```

```text theme={null}
┌─sequenceMatch('(?1)(?2)')(time, equals(number, 1), equals(number, 2), equals(number, 3))─┐
│                                                                                        0 │
└──────────────────────────────────────────────────────────────────────────────────────────┘
```

この場合、3 番のイベントが 1 と 2 の間に発生したため、関数はパターンに一致するイベントチェーンを見つけられませんでした。同じケースで 4 番について条件を確認すると、その数列はパターンに一致します。

```sql theme={null}
SELECT sequenceMatch('(?1)(?2)')(time, number = 1, number = 2, number = 4) FROM t
```

```text theme={null}
┌─sequenceMatch('(?1)(?2)')(time, equals(number, 1), equals(number, 2), equals(number, 4))─┐
│                                                                                        1 │
└──────────────────────────────────────────────────────────────────────────────────────────┘
```

**関連項目**

* [sequenceCount](#sequencecount)

<div id="sequencecount">
  ## sequenceCount
</div>

パターンに一致したイベントチェーンの数をカウントします。この関数は、互いに重ならないイベントチェーンを検索します。現在のチェーンが一致すると、その後から次のチェーンの検索を開始します。

<Note>
  同じ秒に発生したイベントは、数列内で未定義の順序になる場合があり、結果に影響する可能性があります。
</Note>

**構文**

```sql theme={null}
sequenceCount(pattern)(timestamp, cond1, cond2, ...)
```

**引数**

* `timestamp` — 時刻データを含むと見なされるカラム。一般的なデータ型は `Date` と `DateTime` です。また、サポートされている任意の [UInt](/ja/reference/data-types/int-uint) データ型も使用できます。

* `cond1`, `cond2` — イベントチェーンを表す条件。データ型: `UInt8`。条件引数は最大 32 個まで指定できます。関数は、これらの条件で記述されたイベントだけを考慮します。数列にいずれの条件にも記述されていないデータが含まれている場合、関数はそれらをスキップします。

**パラメータ**

* `pattern` — パターン文字列。[パターン構文](#pattern-syntax) を参照してください。

**戻り値**

* 一致した、重複しないイベントチェーンの数。

型: `UInt64`.

**例**

`t` テーブル内のデータを考えます:

```text theme={null}
┌─time─┬─number─┐
│    1 │      1 │
│    2 │      3 │
│    3 │      2 │
│    4 │      1 │
│    5 │      3 │
│    6 │      2 │
└──────┴────────┘
```

数値 1 の後に、間に任意の数のほかの数値を挟んで数値 2 が現れる回数を数えます:

```sql theme={null}
SELECT sequenceCount('(?1).*(?2)')(time, number = 1, number = 2) FROM t
```

```text theme={null}
┌─sequenceCount('(?1).*(?2)')(time, equals(number, 1), equals(number, 2))─┐
│                                                                       2 │
└─────────────────────────────────────────────────────────────────────────┘
```

<div id="sequencematchevents">
  ## sequenceMatchEvents
</div>

パターンに一致した最長のイベントチェーンに含まれるイベントのタイムスタンプを返します。

<Note>
  同じ秒に発生したイベントは、数列内での順序が未定義となる場合があり、結果に影響することがあります。
</Note>

**構文**

```sql theme={null}
sequenceMatchEvents(pattern)(timestamp, cond1, cond2, ...)
```

**引数**

* `timestamp` — 時刻データを含むと見なされるカラム。一般的なデータ型は `Date` と `DateTime` です。サポートされている任意の [UInt](/ja/reference/data-types/int-uint) データ型も使用できます。

* `cond1`, `cond2` — イベントチェーンを記述する条件。データ型: `UInt8`。条件引数は最大 32 個まで渡せます。この関数は、これらの条件で記述されたイベントだけを対象にします。数列に条件で記述されていないデータが含まれている場合、関数はそれらをスキップします。

**パラメーター**

* `pattern` — パターン文字列。[パターン構文](#pattern-syntax) を参照してください。

**戻り値**

* イベントチェーン内で一致した条件引数 (?N) に対応するタイムスタンプの Array。配列内の位置は、パターン内の条件引数の位置に対応します。

型: Array。

**例**

`t` テーブルのデータを考えてみましょう:

```text theme={null}
┌─time─┬─number─┐
│    1 │      1 │
│    2 │      3 │
│    3 │      2 │
│    4 │      1 │
│    5 │      3 │
│    6 │      2 │
└──────┴────────┘
```

最長のチェーン内のイベントのタイムスタンプを返します

```sql theme={null}
SELECT sequenceMatchEvents('(?1).*(?2).*(?1)(?3)')(time, number = 1, number = 2, number = 4) FROM t
```

```text theme={null}
┌─sequenceMatchEvents('(?1).*(?2).*(?1)(?3)')(time, equals(number, 1), equals(number, 2), equals(number, 4))─┐
│ [1,3,4]                                                                                                    │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
```

**関連項目**

* [sequenceMatch](#sequencematch)

<div id="windowfunnel">
  ## windowFunnel
</div>

スライディング時間ウィンドウ内でイベントチェーンを検索し、そのチェーン内で発生したイベントの最大数を計算します。

この関数は、次のアルゴリズムに従って動作します。

* この関数は、チェーン内の最初の条件を満たすデータを探し、イベントカウンターを 1 に設定します。これがスライディングウィンドウの開始時点です。

* チェーン内のイベントがウィンドウ内で順番どおりに発生した場合、カウンターは増加します。イベントの順序が途中で崩れた場合、カウンターは増加しません。

* データに完了度合いの異なる複数のイベントチェーンがある場合、この関数は最も長いチェーンの長さだけを出力します。

**構文**

```sql theme={null}
windowFunnel(window, [mode, [mode, ... ]])(timestamp, cond1, cond2, ..., condN)
```

**引数**

* `timestamp` — タイムスタンプを含むカラム名。サポートされるデータ型: [Date](/ja/reference/data-types/date)、[DateTime](/ja/reference/data-types/datetime)、およびその他の符号なし整数型 (`timestamp` は `UInt64` 型をサポートしますが、その値は Int64 の最大値である 2^63 - 1 を超えることはできません) 。
* `cond` — イベントチェーンを表す条件またはデータ。[UInt8](/ja/reference/data-types/int-uint)。

**パラメータ**

* `window` — スライディングウィンドウの長さ。最初の条件と最後の条件の間の時間間隔を表します。`window` の単位は `timestamp` 自体に依存するため、可変です。これは式 `timestamp of cond1 <= timestamp of cond2 <= ... <= timestamp of condN <= timestamp of cond1 + window` によって定義されます。
* `mode` — オプションの引数です。1 つ以上のモードを設定できます。
  * `'strict_deduplication'` — イベントの数列内で同じ条件が成立した場合、その繰り返しイベントによって以降の処理は中断されます。注意: 同じイベントに対して複数の条件が成立する場合、想定外の動作になることがあります。
  * `'strict_order'` — 他のイベントの介在を許可しません。たとえば `A->B->D->C` の場合、`D` の時点で `A->B->C` の検出を停止し、最大イベントレベルは 2 になります。
  * `'strict_increase'` — タイムスタンプが厳密に増加するイベントにのみ条件を適用します。
  * `'strict_once'` — 条件を複数回満たしていても、イベントチェーン内では各イベントを 1 回だけカウントします。
  * `'allow_reentry'` — 厳密な順序に違反するイベントを無視します。たとえば A->A->B->C の場合、余分な A を無視して A->B->C を検出し、最大イベントレベルは 3 になります。

**戻り値**

スライディング時間ウィンドウ内における、イベントチェーンから連続してトリガーされた条件の最大数。

選択範囲内のすべてのイベントチェーンが解析されます。

型: `Integer`。

**例**

オンラインストアで、ユーザーがスマートフォンを選んで 2 回購入するのに、一定の時間が十分かどうかを判定します。

次のイベントチェーンを設定します。

1. ユーザーがストアのアカウントにログインした (`eventID = 1003`) 。
2. ユーザーがスマートフォンを検索した (`eventID = 1007, product = 'phone'`) 。
3. ユーザーが注文した (`eventID = 1009`) 。
4. ユーザーが再度注文した (`eventID = 1010`) 。

入力テーブル:

```text theme={null}
┌─event_date─┬─user_id─┬───────────timestamp─┬─eventID─┬─product─┐
│ 2019-01-28 │       1 │ 2019-01-29 10:00:00 │    1003 │ phone   │
└────────────┴─────────┴─────────────────────┴─────────┴─────────┘
┌─event_date─┬─user_id─┬───────────timestamp─┬─eventID─┬─product─┐
│ 2019-01-31 │       1 │ 2019-01-31 09:00:00 │    1007 │ phone   │
└────────────┴─────────┴─────────────────────┴─────────┴─────────┘
┌─event_date─┬─user_id─┬───────────timestamp─┬─eventID─┬─product─┐
│ 2019-01-30 │       1 │ 2019-01-30 08:00:00 │    1009 │ phone   │
└────────────┴─────────┴─────────────────────┴─────────┴─────────┘
┌─event_date─┬─user_id─┬───────────timestamp─┬─eventID─┬─product─┐
│ 2019-02-01 │       1 │ 2019-02-01 08:00:00 │    1010 │ phone   │
└────────────┴─────────┴─────────────────────┴─────────┴─────────┘
```

2019年1月から2月の期間に、ユーザー `user_id` がその一連の流れのどこまで到達したかを調べます。

```sql title="Query" theme={null}
SELECT
    level,
    count() AS c
FROM
(
    SELECT
        user_id,
        windowFunnel(6048000000000000)(timestamp, eventID = 1003, eventID = 1009, eventID = 1007, eventID = 1010) AS level
    FROM trend
    WHERE (event_date >= '2019-01-01') AND (event_date <= '2019-02-02')
    GROUP BY user_id
)
GROUP BY level
ORDER BY level ASC;
```

```text title="Response" theme={null}
┌─level─┬─c─┐
│     4 │ 1 │
└───────┴───┘
```

**allow\_reentry モードの例**

この例では、`allow_reentry` モードがユーザーの再入場パターンと組み合わせてどのように機能するかを示します。

```sql theme={null}
-- サンプルデータ: ユーザーがチェックアウト -> 商品詳細 -> 再度チェックアウト -> 支払いの順に操作
-- allow_reentryなし: レベル2で停止（商品詳細ページ）
-- allow_reentryあり: レベル4に到達（支払い完了）

SELECT
    level,
    count() AS users
FROM
(
    SELECT
        user_id,
        windowFunnel(3600, 'strict_order', 'allow_reentry')(
            timestamp,
            action = 'begin_checkout',      -- ステップ1: チェックアウト開始
            action = 'view_product_detail', -- ステップ2: 商品詳細を表示
            action = 'begin_checkout',      -- ステップ3: 再度チェックアウト開始（再エントリ）
            action = 'complete_payment'     -- ステップ4: 支払い完了
        ) AS level
    FROM user_events
    WHERE event_date = today()
    GROUP BY user_id
)
GROUP BY level
ORDER BY level ASC;
```

<div id="retention">
  ## retention
</div>

この関数は引数として、イベントに対して特定の条件が満たされたかどうかを示す `UInt8` 型の条件のセットを 1 個から 32 個まで受け取ります。
任意の条件を引数として指定できます ([WHERE](/ja/reference/statements/select/where) と同様です) 。

最初の条件を除き、各条件は先頭の条件との組み合わせで評価されます。2 番目の結果は 1 番目と 2 番目が true の場合に true になり、3 番目の結果は 1 番目と 3 番目が true の場合に true になり、以下同様です。

**Syntax**

```sql theme={null}
retention(cond1, cond2, ..., cond32);
```

**引数**

* `cond` — `UInt8` の結果 (1 または 0) を返す式。

**戻り値**

1 または 0 の配列。

* 1 — イベントが条件を満たしたことを示します。
* 0 — イベントが条件を満たさなかったことを示します。

型: `UInt8`。

**例**

サイトトラフィックを判定するために `retention` 関数を計算する例を見てみましょう。

**1.** 例を示すためのテーブルを作成します。

```sql title="Query" theme={null}
CREATE TABLE retention_test(date Date, uid Int32) ENGINE = Memory;

INSERT INTO retention_test SELECT '2020-01-01', number FROM numbers(5);
INSERT INTO retention_test SELECT '2020-01-02', number FROM numbers(10);
INSERT INTO retention_test SELECT '2020-01-03', number FROM numbers(15);
```

入力元テーブル:

```sql title="Query" theme={null}
SELECT * FROM retention_test
```

```text title="Response" theme={null}
┌───────date─┬─uid─┐
│ 2020-01-01 │   0 │
│ 2020-01-01 │   1 │
│ 2020-01-01 │   2 │
│ 2020-01-01 │   3 │
│ 2020-01-01 │   4 │
└────────────┴─────┘
┌───────date─┬─uid─┐
│ 2020-01-02 │   0 │
│ 2020-01-02 │   1 │
│ 2020-01-02 │   2 │
│ 2020-01-02 │   3 │
│ 2020-01-02 │   4 │
│ 2020-01-02 │   5 │
│ 2020-01-02 │   6 │
│ 2020-01-02 │   7 │
│ 2020-01-02 │   8 │
│ 2020-01-02 │   9 │
└────────────┴─────┘
┌───────date─┬─uid─┐
│ 2020-01-03 │   0 │
│ 2020-01-03 │   1 │
│ 2020-01-03 │   2 │
│ 2020-01-03 │   3 │
│ 2020-01-03 │   4 │
│ 2020-01-03 │   5 │
│ 2020-01-03 │   6 │
│ 2020-01-03 │   7 │
│ 2020-01-03 │   8 │
│ 2020-01-03 │   9 │
│ 2020-01-03 │  10 │
│ 2020-01-03 │  11 │
│ 2020-01-03 │  12 │
│ 2020-01-03 │  13 │
│ 2020-01-03 │  14 │
└────────────┴─────┘
```

**2.** `retention` 関数を使用して、ユーザーを一意のID `uid` ごとにグループ化します。

```sql title="Query" theme={null}
SELECT
    uid,
    retention(date = '2020-01-01', date = '2020-01-02', date = '2020-01-03') AS r
FROM retention_test
WHERE date IN ('2020-01-01', '2020-01-02', '2020-01-03')
GROUP BY uid
ORDER BY uid ASC
```

```text title="Response" theme={null}
┌─uid─┬─r───────┐
│   0 │ [1,1,1] │
│   1 │ [1,1,1] │
│   2 │ [1,1,1] │
│   3 │ [1,1,1] │
│   4 │ [1,1,1] │
│   5 │ [0,0,0] │
│   6 │ [0,0,0] │
│   7 │ [0,0,0] │
│   8 │ [0,0,0] │
│   9 │ [0,0,0] │
│  10 │ [0,0,0] │
│  11 │ [0,0,0] │
│  12 │ [0,0,0] │
│  13 │ [0,0,0] │
│  14 │ [0,0,0] │
└─────┴─────────┘
```

**3.** 1日あたりのサイト訪問数の合計を計算します。

```sql title="Query" theme={null}
SELECT
    sum(r[1]) AS r1,
    sum(r[2]) AS r2,
    sum(r[3]) AS r3
FROM
(
    SELECT
        uid,
        retention(date = '2020-01-01', date = '2020-01-02', date = '2020-01-03') AS r
    FROM retention_test
    WHERE date IN ('2020-01-01', '2020-01-02', '2020-01-03')
    GROUP BY uid
)
```

```text title="Response" theme={null}
┌─r1─┬─r2─┬─r3─┐
│  5 │  5 │  5 │
└────┴────┴────┘
```

ここで:

* `r1` - 2020-01-01 (`cond1` 条件) にサイトを訪れたユニーク訪問者数。
* `r2` - 2020-01-01 から 2020-01-02 までの特定の期間 (`cond1` および `cond2` 条件) にサイトを訪れたユニーク訪問者数。
* `r3` - 2020-01-01 と 2020-01-03 の特定の期間 (`cond1` および `cond3` 条件) にサイトを訪れたユニーク訪問者数。

<div id="uniquptonx">
  ## uniqUpTo(N)(x)
</div>

指定した上限 `N` までの、引数の異なる値の数を計算します。異なる引数値の数が `N` を超える場合、この関数は `N` + 1 を返し、それ以外の場合は正確な値を計算します。

`N` が小さい場合、最大 10 程度まででの使用を推奨します。`N` の最大値は 100 です。

集約関数の状態では、この関数は 1 + `N` \* 1 つの値のバイト数に相当するメモリを使用します。
文字列を扱う場合、この関数は 8 バイトの非暗号学的ハッシュを格納します。文字列に対する計算は近似になります。

たとえば、Web サイト上でユーザーが実行したすべての検索クエリを記録するテーブルがあるとします。テーブルの各行は 1 件の検索クエリを表し、ユーザー ID、検索クエリ、クエリのタイムスタンプのカラムがあります。`uniqUpTo` を使用すると、少なくとも 5 人のユニークユーザーを生み出したキーワードだけを表示するレポートを生成できます。

```sql theme={null}
SELECT SearchPhrase
FROM SearchLog
GROUP BY SearchPhrase
HAVING uniqUpTo(4)(UserID) >= 5
```

`uniqUpTo(4)(UserID)` は、各 `SearchPhrase` について一意な `UserID` の数を計算しますが、数えるのは最大 4 個までです。ある `SearchPhrase` に対して一意な `UserID` が 4 個を超える場合、この関数は 5 (4 + 1) を返します。次に、`HAVING` 句によって、一意な `UserID` の数が 5 未満の `SearchPhrase` は除外されます。これにより、少なくとも 5 人の異なるユーザーが使用した検索キーワードの一覧を取得できます。

<div id="summapfiltered">
  ## sumMapFiltered
</div>

この関数は、フィルタに使用するキーの配列をパラメータとして受け取る点を除き、[sumMap](/ja/reference/functions/aggregate-functions/sumMap) と同様に動作します。これは、キーのカーディナリティが高い場合に特に役立ちます。

**構文**

`sumMapFiltered(keys_to_keep)(keys, values)`

**パラメータ**

* `keys_to_keep`: フィルタに使用するキーの [Array](/ja/reference/data-types/array)。
* `keys`: キーの [Array](/ja/reference/data-types/array)。
* `values`: 値の [Array](/ja/reference/data-types/array)。

**戻り値**

* 2 つの配列からなるタプルを返します。1 つはソート順に並んだキー、もう 1 つは対応するキーごとに合計された値です。

**例**

```sql title="Query" theme={null}
CREATE TABLE sum_map
(
    `date` Date,
    `timeslot` DateTime,
    `statusMap` Nested(status UInt16, requests UInt64)
)
ENGINE = Log

INSERT INTO sum_map VALUES
    ('2000-01-01', '2000-01-01 00:00:00', [1, 2, 3], [10, 10, 10]),
    ('2000-01-01', '2000-01-01 00:00:00', [3, 4, 5], [10, 10, 10]),
    ('2000-01-01', '2000-01-01 00:01:00', [4, 5, 6], [10, 10, 10]),
    ('2000-01-01', '2000-01-01 00:01:00', [6, 7, 8], [10, 10, 10]);
```

```sql title="Query" theme={null}
SELECT sumMapFiltered([1, 4, 8])(statusMap.status, statusMap.requests) FROM sum_map;
```

```response title="Response" theme={null}
   ┌─sumMapFiltered([1, 4, 8])(statusMap.status, statusMap.requests)─┐
1. │ ([1,4,8],[10,20,10])                                            │
   └─────────────────────────────────────────────────────────────────┘
```

<div id="summapfilteredwithoverflow">
  ## sumMapFilteredWithOverflow
</div>

この関数は、フィルタに使用するキーの配列をパラメータとして受け取る点を除き、[sumMap](/ja/reference/functions/aggregate-functions/sumMap) と同様に動作します。特に、キーのカーディナリティが高い場合に有用です。[sumMapFiltered](#summapfiltered) 関数との違いは、オーバーフローを許容したまま合計を行う点です。つまり、合計結果のデータ型は引数のデータ型と同じになります。

**構文**

`sumMapFilteredWithOverflow(keys_to_keep)(keys, values)`

**パラメータ**

* `keys_to_keep`: フィルタに使用するキーの [Array](/ja/reference/data-types/array)。
* `keys`: キーの [Array](/ja/reference/data-types/array)。
* `values`: 値の [Array](/ja/reference/data-types/array)。

**戻り値**

* 2 つの配列からなるタプルを返します。キーはソート順で、値は対応するキーごとに合計されます。

**例**

この例では、`sum_map` テーブルを作成し、いくつかのデータを挿入したあと、結果を比較するために `sumMapFilteredWithOverflow`、`sumMapFiltered`、および `toTypeName` 関数を使用します。作成したテーブルでは `requests` の型は `UInt8` ですが、`sumMapFiltered` はオーバーフローを避けるために、合計後の値の型を `UInt64` に昇格させます。一方、`sumMapFilteredWithOverflow` は型を `UInt8` のまま保持します。この型は結果を格納するには十分な大きさではないため、つまりオーバーフローが発生します。

```sql title="Query" theme={null}
CREATE TABLE sum_map
(
    `date` Date,
    `timeslot` DateTime,
    `statusMap` Nested(status UInt8, requests UInt8)
)
ENGINE = Log

INSERT INTO sum_map VALUES
    ('2000-01-01', '2000-01-01 00:00:00', [1, 2, 3], [10, 10, 10]),
    ('2000-01-01', '2000-01-01 00:00:00', [3, 4, 5], [10, 10, 10]),
    ('2000-01-01', '2000-01-01 00:01:00', [4, 5, 6], [10, 10, 10]),
    ('2000-01-01', '2000-01-01 00:01:00', [6, 7, 8], [10, 10, 10]);
```

```sql title="Query" theme={null}
SELECT sumMapFilteredWithOverflow([1, 4, 8])(statusMap.status, statusMap.requests) as summap_overflow, toTypeName(summap_overflow) FROM sum_map;
```

```sql title="Query" theme={null}
SELECT sumMapFiltered([1, 4, 8])(statusMap.status, statusMap.requests) as summap, toTypeName(summap) FROM sum_map;
```

```response title="Response" theme={null}
   ┌─sum──────────────────┬─toTypeName(sum)───────────────────┐
1. │ ([1,4,8],[10,20,10]) │ Tuple(Array(UInt8), Array(UInt8)) │
   └──────────────────────┴───────────────────────────────────┘
```

```response title="Response" theme={null}
   ┌─summap───────────────┬─toTypeName(summap)─────────────────┐
1. │ ([1,4,8],[10,20,10]) │ Tuple(Array(UInt8), Array(UInt64)) │
   └──────────────────────┴────────────────────────────────────┘
```

<div id="sequencenextnode">
  ## sequenceNextNode
</div>

イベントチェーンに一致する次のイベントの値を返します。

*実験的な関数です。使用するには `SET allow_experimental_funnel_functions = 1` を設定します。*

**構文**

```sql theme={null}
sequenceNextNode(direction, base)(timestamp, event_column, base_condition, event1, event2, event3, ...)
```

**パラメータ**

* `direction` — 方向を指定するために使用します。
  * forward — 前方に進みます。
  * backward — 後方に進みます。

* `base` — 基準点を設定するために使用します。
  * head — 基準点を最初のイベントに設定します。
  * tail — 基準点を最後のイベントに設定します。
  * first\_match — 基準点を最初に一致した `event1` に設定します。
  * last\_match — 基準点を最後に一致した `event1` に設定します。

**引数**

* `timestamp` — タイムスタンプを含むカラムの名前。サポートされるデータ型: [Date](/ja/reference/data-types/date)、[DateTime](/ja/reference/data-types/datetime)、およびその他の符号なし整数型。
* `event_column` — 戻り値として返される次のイベントの値を含むカラムの名前。サポートされるデータ型: [String](/ja/reference/data-types/string) および [Nullable(String)](/ja/reference/data-types/nullable)。
* `base_condition` — 基準点が満たす必要のある条件。
* `event1`, `event2`, ... — イベントチェーンを記述する条件。[UInt8](/ja/reference/data-types/int-uint)。

**戻り値**

* `event_column[next_index]` — パターンに一致し、次の値が存在する場合。
* `NULL` - パターンに一致しない場合、または次の値が存在しない場合。

型: [Nullable(String)](/ja/reference/data-types/nullable)。

**例**

イベントが A->B->C->D->E のときに、B->C に続くイベント、つまり D を知りたい場合に使用できます。

A->B に続くイベントを検索するクエリステートメント:

```sql title="Query" theme={null}
CREATE TABLE test_flow (
    dt DateTime,
    id int,
    page String)
ENGINE = MergeTree()
PARTITION BY toYYYYMMDD(dt)
ORDER BY id;

INSERT INTO test_flow VALUES (1, 1, 'A') (2, 1, 'B') (3, 1, 'C') (4, 1, 'D') (5, 1, 'E');

SELECT id, sequenceNextNode('forward', 'head')(dt, page, page = 'A', page = 'A', page = 'B') as next_flow FROM test_flow GROUP BY id;
```

```text title="Response" theme={null}
┌─id─┬─next_flow─┐
│  1 │ C         │
└────┴───────────┘
```

**`forward` と `head` の動作**

```sql theme={null}
ALTER TABLE test_flow DELETE WHERE 1 = 1 settings mutations_sync = 1;

INSERT INTO test_flow VALUES (1, 1, 'Home') (2, 1, 'Gift') (3, 1, 'Exit');
INSERT INTO test_flow VALUES (1, 2, 'Home') (2, 2, 'Home') (3, 2, 'Gift') (4, 2, 'Basket');
INSERT INTO test_flow VALUES (1, 3, 'Gift') (2, 3, 'Home') (3, 3, 'Gift') (4, 3, 'Basket');
```

```sql theme={null}
SELECT id, sequenceNextNode('forward', 'head')(dt, page, page = 'Home', page = 'Home', page = 'Gift') FROM test_flow GROUP BY id;

                  dt   id   page
 1970-01-01 09:00:01    1   Home // 基準点、Homeと一致
 1970-01-01 09:00:02    1   Gift // Giftと一致
 1970-01-01 09:00:03    1   Exit // 結果

 1970-01-01 09:00:01    2   Home // 基準点、Homeと一致
 1970-01-01 09:00:02    2   Home // Giftと不一致
 1970-01-01 09:00:03    2   Gift
 1970-01-01 09:00:04    2   Basket

 1970-01-01 09:00:01    3   Gift // 基準点、Homeと不一致
 1970-01-01 09:00:02    3   Home
 1970-01-01 09:00:03    3   Gift
 1970-01-01 09:00:04    3   Basket
```

**`backward` と `tail` の動作**

```sql theme={null}
SELECT id, sequenceNextNode('backward', 'tail')(dt, page, page = 'Basket', page = 'Basket', page = 'Gift') FROM test_flow GROUP BY id;

                 dt   id   page
1970-01-01 09:00:01    1   Home
1970-01-01 09:00:02    1   Gift
1970-01-01 09:00:03    1   Exit // 基準点、Basketと不一致

1970-01-01 09:00:01    2   Home
1970-01-01 09:00:02    2   Home // 結果
1970-01-01 09:00:03    2   Gift // Giftと一致
1970-01-01 09:00:04    2   Basket // 基準点、Basketと一致

1970-01-01 09:00:01    3   Gift
1970-01-01 09:00:02    3   Home // 結果
1970-01-01 09:00:03    3   Gift // 基準点、Giftと一致
1970-01-01 09:00:04    3   Basket // 基準点、Basketと一致
```

**`forward` と `first_match` の挙動**

```sql theme={null}
SELECT id, sequenceNextNode('forward', 'first_match')(dt, page, page = 'Gift', page = 'Gift') FROM test_flow GROUP BY id;

                 dt   id   page
1970-01-01 09:00:01    1   Home
1970-01-01 09:00:02    1   Gift // 基準点
1970-01-01 09:00:03    1   Exit // 結果

1970-01-01 09:00:01    2   Home
1970-01-01 09:00:02    2   Home
1970-01-01 09:00:03    2   Gift // 基準点
1970-01-01 09:00:04    2   Basket  The result

1970-01-01 09:00:01    3   Gift // 基準点
1970-01-01 09:00:02    3   Home // 結果
1970-01-01 09:00:03    3   Gift
1970-01-01 09:00:04    3   Basket
```

```sql theme={null}
SELECT id, sequenceNextNode('forward', 'first_match')(dt, page, page = 'Gift', page = 'Gift', page = 'Home') FROM test_flow GROUP BY id;

                 dt   id   page
1970-01-01 09:00:01    1   Home
1970-01-01 09:00:02    1   Gift // 基準点
1970-01-01 09:00:03    1   Exit // Home に一致しない

1970-01-01 09:00:01    2   Home
1970-01-01 09:00:02    2   Home
1970-01-01 09:00:03    2   Gift // 基準点
1970-01-01 09:00:04    2   Basket // Home に一致しない

1970-01-01 09:00:01    3   Gift // 基準点
1970-01-01 09:00:02    3   Home // Home に一致
1970-01-01 09:00:03    3   Gift // 結果
1970-01-01 09:00:04    3   Basket
```

**`backward` と `last_match` の動作**

```sql theme={null}
SELECT id, sequenceNextNode('backward', 'last_match')(dt, page, page = 'Gift', page = 'Gift') FROM test_flow GROUP BY id;

                 dt   id   page
1970-01-01 09:00:01    1   Home // 結果
1970-01-01 09:00:02    1   Gift // 基準点
1970-01-01 09:00:03    1   Exit

1970-01-01 09:00:01    2   Home
1970-01-01 09:00:02    2   Home // 結果
1970-01-01 09:00:03    2   Gift // 基準点
1970-01-01 09:00:04    2   Basket

1970-01-01 09:00:01    3   Gift
1970-01-01 09:00:02    3   Home // 結果
1970-01-01 09:00:03    3   Gift // 基準点
1970-01-01 09:00:04    3   Basket
```

```sql theme={null}
SELECT id, sequenceNextNode('backward', 'last_match')(dt, page, page = 'Gift', page = 'Gift', page = 'Home') FROM test_flow GROUP BY id;

                 dt   id   page
1970-01-01 09:00:01    1   Home // Homeと一致、結果はnull
1970-01-01 09:00:02    1   Gift // 基準点
1970-01-01 09:00:03    1   Exit

1970-01-01 09:00:01    2   Home // 結果
1970-01-01 09:00:02    2   Home // Homeと一致
1970-01-01 09:00:03    2   Gift // 基準点
1970-01-01 09:00:04    2   Basket

1970-01-01 09:00:01    3   Gift // 結果
1970-01-01 09:00:02    3   Home // Homeと一致
1970-01-01 09:00:03    3   Gift // 基準点
1970-01-01 09:00:04    3   Basket
```

**`base_condition` の動作**

```sql theme={null}
CREATE TABLE test_flow_basecond
(
    `dt` DateTime,
    `id` int,
    `page` String,
    `ref` String
)
ENGINE = MergeTree
PARTITION BY toYYYYMMDD(dt)
ORDER BY id;

INSERT INTO test_flow_basecond VALUES (1, 1, 'A', 'ref4') (2, 1, 'A', 'ref3') (3, 1, 'B', 'ref2') (4, 1, 'B', 'ref1');
```

```sql theme={null}
SELECT id, sequenceNextNode('forward', 'head')(dt, page, ref = 'ref1', page = 'A') FROM test_flow_basecond GROUP BY id;

                  dt   id   page   ref
 1970-01-01 09:00:01    1   A      ref4 // headのrefカラムが'ref1'と一致しないため、headは基準点になれません。
 1970-01-01 09:00:02    1   A      ref3
 1970-01-01 09:00:03    1   B      ref2
 1970-01-01 09:00:04    1   B      ref1
```

```sql theme={null}
SELECT id, sequenceNextNode('backward', 'tail')(dt, page, ref = 'ref4', page = 'B') FROM test_flow_basecond GROUP BY id;

                  dt   id   page   ref
 1970-01-01 09:00:01    1   A      ref4
 1970-01-01 09:00:02    1   A      ref3
 1970-01-01 09:00:03    1   B      ref2
 1970-01-01 09:00:04    1   B      ref1 // tailのrefカラムが'ref4'と一致しないため、tailは基準点になれません。
```

```sql theme={null}
SELECT id, sequenceNextNode('forward', 'first_match')(dt, page, ref = 'ref3', page = 'A') FROM test_flow_basecond GROUP BY id;

                  dt   id   page   ref
 1970-01-01 09:00:01    1   A      ref4 // この行は、refカラムが 'ref3' と一致しないため、基準点 にはなりません。
 1970-01-01 09:00:02    1   A      ref3 // 基準点
 1970-01-01 09:00:03    1   B      ref2 // 結果
 1970-01-01 09:00:04    1   B      ref1
```

```sql theme={null}
SELECT id, sequenceNextNode('backward', 'last_match')(dt, page, ref = 'ref2', page = 'B') FROM test_flow_basecond GROUP BY id;

                  dt   id   page   ref
 1970-01-01 09:00:01    1   A      ref4
 1970-01-01 09:00:02    1   A      ref3 // 結果
 1970-01-01 09:00:03    1   B      ref2 // 基準点
 1970-01-01 09:00:04    1   B      ref1 // この行はrefカラムが'ref2'と一致しないため、基準点になれません。
```
