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

> Documentation des fonctions d’agrégation paramétriques

# Fonctions d’agrégation paramétriques

Certaines fonctions d’agrégation acceptent non seulement des colonnes d’arguments (utilisées pour la compression), mais aussi un ensemble de paramètres — des constantes d’initialisation. La syntaxe comporte deux paires de parenthèses au lieu d’une seule. La première est destinée aux paramètres, la seconde aux arguments.

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

Calcule un histogramme adaptatif. Les résultats précis ne sont pas garantis.

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

La fonction utilise [A Streaming Parallel Decision Tree Algorithm](http://jmlr.org/papers/volume11/ben-haim10a/ben-haim10a.pdf). Les limites des classes de l’histogramme sont ajustées à mesure que de nouvelles données sont transmises à la fonction. En général, les largeurs des classes ne sont pas égales.

**Arguments**

`values` — [Expression](/fr/reference/syntax#expressions) produisant des valeurs d’entrée.

**Paramètres**

`number_of_bins` — Limite supérieure du nombre de classes dans l’histogramme. La fonction calcule automatiquement le nombre de classes. Elle essaie d’atteindre le nombre de classes spécifié, mais si elle n’y parvient pas, elle en utilise moins.

**Valeurs renvoyées**

* [Array](/fr/reference/data-types/array) de [Tuples](/fr/reference/data-types/tuple) au format suivant :

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

  * `lower` — Borne inférieure de la classe.
  * `upper` — Borne supérieure de la classe.
  * `height` — Hauteur calculée de la classe.

**Exemple**

```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)] │
└─────────────────────────────────────────────────────────────────────────┘
```

Vous pouvez visualiser un histogramme avec la fonction [bar](/fr/reference/functions/regular-functions/other-functions#bar), par exemple :

```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 │ ██▌   │
└────────┴───────┘
```

Dans ce cas, gardez à l’esprit que vous ne connaissez pas les bornes des intervalles de l’histogramme.

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

Vérifie si la séquence contient une chaîne d'événements correspondant au motif.

**Syntaxe**

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

<Note>
  Les événements qui se produisent au cours de la même seconde peuvent figurer dans la séquence dans un ordre indéfini, ce qui peut affecter le résultat.
</Note>

**Arguments**

* `timestamp` — Colonne considérée comme contenant des données temporelles. Les types de données typiques sont `Date` et `DateTime`. Vous pouvez également utiliser n’importe lequel des types de données [UInt](/fr/reference/data-types/int-uint) pris en charge.

* `cond1`, `cond2` — Conditions qui décrivent la chaîne d’événements. Type de données : `UInt8`. Vous pouvez transmettre jusqu’à 32 arguments de condition. La fonction ne prend en compte que les événements décrits dans ces conditions. Si la séquence contient des données non décrites par une condition, la fonction les ignore.

**Paramètres**

* `pattern` — Chaîne de motif. Voir [Syntaxe du motif](#pattern-syntax).

**Valeurs renvoyées**

* 1, si le motif correspond.
* 0, si le motif ne correspond pas.

Type : `UInt8`.

<div id="pattern-syntax">
  #### Syntaxe du motif
</div>

* `(?N)` — Correspond à l'argument de condition à la position `N`. Les conditions sont numérotées dans la plage `[1, 32]`. Par exemple, `(?1)` correspond à l'argument transmis au paramètre `cond1`.

* `.*` — Correspond à un nombre quelconque d'événements. Il n'est pas nécessaire de fournir des arguments de condition pour faire correspondre cet élément du motif.

* `(?t operator value)` — Définit l'intervalle de temps, en secondes, qui doit séparer deux événements. Par exemple, le motif `(?1)(?t>1800)(?2)` correspond à des événements qui se produisent à plus de 1800 secondes d'intervalle. Un nombre quelconque d'événements peut se trouver entre ces événements. Vous pouvez utiliser les opérateurs `>=`, `>`, `<`, `<=`, `==`.

**Exemples**

Considérez les données de la table `t` :

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

Exécutez la requête :

```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 │
└───────────────────────────────────────────────────────────────────────┘
```

La fonction a trouvé la chaîne d’événements dans laquelle le nombre 2 suit le nombre 1. Elle a ignoré le nombre 3 entre les deux, car ce nombre n’est pas défini comme un événement. Si nous voulons tenir compte de ce nombre lors de la recherche de la chaîne d’événements donnée dans l’exemple, nous devons définir une condition pour celui-ci.

```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 │
└──────────────────────────────────────────────────────────────────────────────────────────┘
```

Dans ce cas, la fonction n’a pas pu trouver la chaîne d’événements correspondant au motif, car l’événement associé au nombre 3 s’est produit entre 1 et 2. Si, dans ce même cas, nous vérifiions la condition pour le nombre 4, la séquence correspondrait au motif.

```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 │
└──────────────────────────────────────────────────────────────────────────────────────────┘
```

**Voir aussi**

* [sequenceCount](#sequencecount)

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

Compte le nombre de chaînes d’événements correspondant au motif. La fonction recherche des chaînes d’événements qui ne se chevauchent pas. Elle commence à rechercher la chaîne suivante après la correspondance de la chaîne en cours.

<Note>
  Les événements qui se produisent à la même seconde peuvent se trouver dans la séquence dans un ordre indéfini, ce qui affecte le résultat.
</Note>

**Syntaxe**

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

**Arguments**

* `timestamp` — Colonne considérée comme contenant des données temporelles. Les types de données les plus courants sont `Date` et `DateTime`. Vous pouvez également utiliser n’importe lequel des types de données [UInt](/fr/reference/data-types/int-uint) pris en charge.

* `cond1`, `cond2` — Conditions décrivant la chaîne d’événements. Type de données : `UInt8`. Vous pouvez fournir jusqu’à 32 arguments de condition. La fonction prend uniquement en compte les événements décrits par ces conditions. Si la séquence contient des données qui ne sont décrites par aucune condition, la fonction les ignore.

**Paramètres**

* `pattern` — Chaîne de motif. Voir [Syntaxe du motif](#pattern-syntax).

**Valeurs renvoyées**

* Nombre de chaînes d’événements non chevauchantes correspondantes.

Type : `UInt64`.

**Exemple**

Considérez les données de la table `t` :

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

Comptez le nombre de fois où le nombre 2 apparaît après le nombre 1, quel que soit le nombre d’autres nombres entre les deux :

```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>

Renvoie les horodatages des plus longues chaînes d’événements correspondant au motif.

<Note>
  Les événements qui se produisent à la même seconde peuvent apparaître dans la séquence dans un ordre indéfini, ce qui affecte le résultat.
</Note>

**Syntaxe**

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

**Arguments**

* `timestamp` — Colonne considérée comme contenant des données temporelles. Les types de données les plus courants sont `Date` et `DateTime`. Vous pouvez également utiliser n’importe lequel des types de données [UInt](/fr/reference/data-types/int-uint) pris en charge.

* `cond1`, `cond2` — Conditions qui décrivent la chaîne d’événements. Type de données : `UInt8`. Vous pouvez fournir jusqu’à 32 arguments de condition. La fonction ne prend en compte que les événements décrits dans ces conditions. Si la séquence contient des données qui ne sont décrites dans aucune condition, la fonction les ignore.

**Paramètres**

* `pattern` — Chaîne de motif. Voir [Syntaxe du motif](#pattern-syntax).

**Valeurs renvoyées**

* Array d’horodatages pour les arguments de condition correspondants (?N) de la chaîne d’événements. La position dans le tableau correspond à celle de l’argument de condition dans le motif.

Type : Array.

**Exemple**

Prenons les données de la table `t` :

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

Renvoie les horodatages des événements de la plus longue chaîne

```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]                                                                                                    │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
```

**Voir aussi**

* [sequenceMatch](#sequencematch)

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

Recherche des chaînes d’événements dans une fenêtre temporelle glissante et calcule le nombre maximal d’événements survenus dans la chaîne.

La fonction suit l’algorithme suivant :

* La fonction recherche les données qui satisfont à la première condition de la chaîne et fixe le compteur d’événements à 1. C’est à ce moment que la fenêtre glissante démarre.

* Si des événements de la chaîne se produisent successivement dans la fenêtre, le compteur est incrémenté. Si la séquence d’événements est interrompue, le compteur n’est pas incrémenté.

* Si les données contiennent plusieurs chaînes d’événements à différents stades d’avancement, la fonction renvoie uniquement la longueur de la chaîne la plus longue.

**Syntaxe**

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

**Arguments**

* `timestamp` — Nom de la colonne contenant le timestamp. Types de données pris en charge : [Date](/fr/reference/data-types/date), [DateTime](/fr/reference/data-types/datetime) et autres types entiers non signés (notez que même si `timestamp` prend en charge le type `UInt64`, sa valeur ne peut pas dépasser la valeur maximale de `Int64`, soit 2^63 - 1).
* `cond` — Conditions ou données décrivant la chaîne d'événements. [UInt8](/fr/reference/data-types/int-uint).

**Paramètres**

* `window` — Longueur de la fenêtre glissante ; il s'agit de l'intervalle de temps entre la première et la dernière condition. L'unité de `window` dépend de `timestamp` lui-même et peut varier. Elle est déterminée à l'aide de l'expression `timestamp of cond1 <= timestamp of cond2 <= ... <= timestamp of condN <= timestamp of cond1 + window`.
* `mode` — Argument facultatif. Un ou plusieurs modes peuvent être définis.
  * `'strict_deduplication'` — Si la même condition est vérifiée pour une séquence d'événements, cet événement répété interrompt la suite du traitement. Remarque : le comportement peut être inattendu si plusieurs conditions sont vérifiées pour un même événement.
  * `'strict_order'` — N'autorise pas l'intercalation d'autres événements. Par ex., dans le cas de `A->B->D->C`, la détection de `A->B->C` s'arrête à `D` et le niveau maximal d'événement est 2.
  * `'strict_increase'` — Applique les conditions uniquement aux événements dont les timestamps sont strictement croissants.
  * `'strict_once'` — Ne compte chaque événement qu'une seule fois dans la chaîne, même s'il satisfait la condition plusieurs fois.
  * `'allow_reentry'` — Ignore les événements qui ne respectent pas l'ordre strict. Par ex., dans le cas de A->A->B->C, il détecte A->B->C en ignorant le A redondant et le niveau maximal d'événement est 3.

**Valeur renvoyée**

Le nombre maximal de conditions consécutives déclenchées dans la chaîne à l'intérieur de la fenêtre de temps glissante.
Toutes les chaînes de la sélection sont analysées.

Type : `Integer`.

**Exemple**

Déterminez si une période donnée est suffisante pour qu'un utilisateur sélectionne un téléphone et l'achète deux fois dans la boutique en ligne.

Définissez la chaîne d'événements suivante :

1. L'utilisateur s'est connecté à son compte sur la boutique (`eventID = 1003`).
2. L'utilisateur recherche un téléphone (`eventID = 1007, product = 'phone'`).
3. L'utilisateur a passé une commande (`eventID = 1009`).
4. L'utilisateur a de nouveau passé la commande (`eventID = 1010`).

Table d'entrée :

```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   │
└────────────┴─────────┴─────────────────────┴─────────┴─────────┘
```

Déterminez jusqu’où l’utilisateur `user_id` a pu progresser dans la chaîne au cours d’une période entre janvier et février 2019.

```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 │
└───────┴───┘
```

**Exemple avec le mode allow\_reentry**

Cet exemple illustre le fonctionnement du mode `allow_reentry` avec les modèles de réentrée utilisateur :

```sql theme={null}
-- Sample data: user visits checkout -> product detail -> checkout again -> payment
-- Without allow_reentry: stops at level 2 (product detail page)
-- With allow_reentry: reaches level 4 (payment completion)

SELECT
    level,
    count() AS users
FROM
(
    SELECT
        user_id,
        windowFunnel(3600, 'strict_order', 'allow_reentry')(
            timestamp,
            action = 'begin_checkout',      -- Step 1: Begin checkout
            action = 'view_product_detail', -- Step 2: View product detail  
            action = 'begin_checkout',      -- Step 3: Begin checkout again (reentry)
            action = 'complete_payment'     -- Step 4: Complete payment
        ) 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>

La fonction prend en argument un ensemble de conditions, de 1 à 32 arguments de type `UInt8`, qui indiquent si une condition donnée a été remplie pour l'événement.
N'importe quelle condition peut être spécifiée comme argument (comme dans [WHERE](/fr/reference/statements/select/where)).

Les conditions, à l'exception de la première, s'appliquent par paires : le résultat de la deuxième sera true si la première et la deuxième sont true, celui de la troisième si la première et la troisième sont true, etc.

**Syntaxe**

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

**Arguments**

* `cond` — Une expression qui renvoie un résultat `UInt8` (1 ou 0).

**Valeur renvoyée**

Le tableau contenant 1 ou 0.

* 1 — La condition est remplie pour l’événement.
* 0 — La condition n’est pas remplie pour l’événement.

Type : `UInt8`.

**Exemple**

Prenons l’exemple du calcul de la fonction `retention` pour déterminer le trafic du site.

**1.** Créez une table pour illustrer cet exemple.

```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);
```

Table d’entrée :

```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.** Regroupez les utilisateurs selon leur identifiant unique `uid` à l’aide de la fonction `retention`.

```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.** Calculez le nombre total de visites sur le site par jour.

```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 │
└────┴────┴────┘
```

Où :

* `r1`- le nombre de visiteurs uniques ayant visité le site le 2020-01-01 (la condition `cond1`).
* `r2`- le nombre de visiteurs uniques ayant visité le site durant une période donnée entre 2020-01-01 et 2020-01-02 (les conditions `cond1` et `cond2`).
* `r3`- le nombre de visiteurs uniques ayant visité le site durant une période donnée les 2020-01-01 et 2020-01-03 (les conditions `cond1` et `cond3`).

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

Calcule le nombre de valeurs distinctes de l’argument jusqu’à une limite donnée, `N`. Si le nombre de valeurs d’argument distinctes est supérieur à `N`, cette fonction renvoie `N` + 1 ; sinon, elle calcule la valeur exacte.

Recommandée pour de petites valeurs de `N`, jusqu’à 10. La valeur maximale de `N` est 100.

Pour l’état d’une fonction d’agrégation, cette fonction utilise une quantité de mémoire égale à 1 + `N` \* la taille en octets d’une valeur.
Lorsqu’il s’agit de chaînes, cette fonction stocke un hash non cryptographique de 8 octets ; le calcul est approximatif pour les chaînes.

Par exemple, si vous avez une table qui enregistre chaque requête de recherche effectuée par les utilisateurs sur votre site web. Chaque ligne de la table représente une seule requête de recherche, avec des colonnes pour l’ID utilisateur, la requête de recherche et le timestamp de la requête. Vous pouvez utiliser `uniqUpTo` pour générer un rapport qui n’affiche que les mots-clés ayant produit au moins 5 utilisateurs uniques.

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

`uniqUpTo(4)(UserID)` calcule le nombre de valeurs `UserID` distinctes pour chaque `SearchPhrase`, mais n’en compte que 4 au maximum. S’il y a plus de 4 valeurs `UserID` distinctes pour une `SearchPhrase`, la fonction renvoie 5 (4 + 1). La clause `HAVING` filtre ensuite les valeurs `SearchPhrase` pour lesquelles le nombre de valeurs `UserID` distinctes est inférieur à 5. Vous obtiendrez ainsi une liste de mots-clés de recherche utilisés par au moins 5 utilisateurs distincts.

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

Cette fonction se comporte comme [sumMap](/fr/reference/functions/aggregate-functions/sumMap), sauf qu’elle accepte également, en paramètre, un tableau de clés servant de filtre. Cela peut être particulièrement utile lorsque vous travaillez avec des clés à forte cardinalité.

**Syntaxe**

`sumMapFiltered(keys_to_keep)(keys, values)`

**Paramètres**

* `keys_to_keep`: [Array](/fr/reference/data-types/array) de clés à utiliser pour le filtrage.
* `keys`: [Array](/fr/reference/data-types/array) de clés.
* `values`: [Array](/fr/reference/data-types/array) de valeurs.

**Valeur renvoyée**

* Renvoie un tuple de deux tableaux : les clés dans l’ordre trié et les valeurs additionnées pour les clés correspondantes.

**Exemple**

```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>

Cette fonction se comporte de la même manière que [sumMap](/fr/reference/functions/aggregate-functions/sumMap), à la différence qu'elle accepte également en paramètre un tableau de clés sur lequel appliquer un filtre. Cela peut être particulièrement utile lorsque l'on travaille avec une forte cardinalité de clés. Elle diffère de la fonction [sumMapFiltered](#summapfiltered) en ce qu'elle effectue la sommation avec overflow, c'est-à-dire qu'elle renvoie le même type de données pour la sommation que le type de données de l'argument.

**Syntaxe**

`sumMapFilteredWithOverflow(keys_to_keep)(keys, values)`

**Paramètres**

* `keys_to_keep` : [Array](/fr/reference/data-types/array) de clés à utiliser pour le filtre.
* `keys` : [Array](/fr/reference/data-types/array) de clés.
* `values` : [Array](/fr/reference/data-types/array) de valeurs.

**Valeur renvoyée**

* Renvoie un tuple de deux tableaux : les clés dans l'ordre trié, et les valeurs additionnées pour les clés correspondantes.

**Exemple**

Dans cet exemple, nous créons une table `sum_map`, y insérons des données, puis utilisons `sumMapFilteredWithOverflow`, `sumMapFiltered` et la fonction `toTypeName` pour comparer le résultat. Alors que `requests` était de type `UInt8` dans la table créée, `sumMapFiltered` a converti le type des valeurs additionnées en `UInt64` pour éviter un overflow, tandis que `sumMapFilteredWithOverflow` a conservé le type `UInt8`, qui n'est pas assez grand pour stocker le résultat, c'est-à-dire qu'un overflow s'est produit.

```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>

Renvoie la valeur de l’événement suivant qui correspond à une chaîne d’événements.

*Fonction expérimentale, `SET allow_experimental_funnel_functions = 1` pour l’activer.*

**Syntaxe**

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

**Paramètres**

* `direction` — Sert à définir le sens de navigation.
  * forward — Vers l’avant.
  * backward — Vers l’arrière.

* `base` — Sert à définir le point de base.
  * head — Définit le point de base sur le premier événement.
  * tail — Définit le point de base sur le dernier événement.
  * first\_match — Définit le point de base sur le premier `event1` correspondant.
  * last\_match — Définit le point de base sur le dernier `event1` correspondant.

**Arguments**

* `timestamp` — Nom de la colonne contenant l’horodatage. Types de données pris en charge : [Date](/fr/reference/data-types/date), [DateTime](/fr/reference/data-types/datetime) et d’autres types d’entiers non signés.
* `event_column` — Nom de la colonne contenant la valeur du prochain événement à renvoyer. Types de données pris en charge : [String](/fr/reference/data-types/string) et [Nullable(String)](/fr/reference/data-types/nullable).
* `base_condition` — Condition que le point de base doit satisfaire.
* `event1`, `event2`, ... — Conditions décrivant la chaîne d’événements. [UInt8](/fr/reference/data-types/int-uint).

**Valeurs renvoyées**

* `event_column[next_index]` — Si le motif correspond et que la valeur suivante existe.
* `NULL` - Si le motif ne correspond pas ou que la valeur suivante n’existe pas.

Type : [Nullable(String)](/fr/reference/data-types/nullable).

**Exemple**

Cette fonction peut être utilisée lorsque les événements sont A->B->C->D->E et que vous voulez connaître l’événement qui suit B->C, c’est-à-dire D.

La requête suivante recherche l’événement qui suit 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         │
└────┴───────────┘
```

**Comportement de `forward` et de `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 // point de base, Matched with Home
 1970-01-01 09:00:02    1   Gift // Matched with Gift
 1970-01-01 09:00:03    1   Exit // The result

 1970-01-01 09:00:01    2   Home // point de base, Matched with Home
 1970-01-01 09:00:02    2   Home // Unmatched with 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 // point de base, Unmatched with 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
```

**Comportement de `backward` et de `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 // point de base, Unmatched with Basket

1970-01-01 09:00:01    2   Home
1970-01-01 09:00:02    2   Home // The result
1970-01-01 09:00:03    2   Gift // Matched with Gift
1970-01-01 09:00:04    2   Basket // point de base, Matched with Basket

1970-01-01 09:00:01    3   Gift
1970-01-01 09:00:02    3   Home // The result
1970-01-01 09:00:03    3   Gift // point de base, Matched with Gift
1970-01-01 09:00:04    3   Basket // point de base, Matched with Basket
```

**Comportement de `forward` et de `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 // point de base
1970-01-01 09:00:03    1   Exit // The result

1970-01-01 09:00:01    2   Home
1970-01-01 09:00:02    2   Home
1970-01-01 09:00:03    2   Gift // point de base
1970-01-01 09:00:04    2   Basket  The result

1970-01-01 09:00:01    3   Gift // point de base
1970-01-01 09:00:02    3   Home // The result
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 // point de base
1970-01-01 09:00:03    1   Exit // Unmatched with 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 // point de base
1970-01-01 09:00:04    2   Basket // Unmatched with Home

1970-01-01 09:00:01    3   Gift // point de base
1970-01-01 09:00:02    3   Home // Matched with Home
1970-01-01 09:00:03    3   Gift // The result
1970-01-01 09:00:04    3   Basket
```

**Comportement de `backward` et `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 // The result
1970-01-01 09:00:02    1   Gift // point de base
1970-01-01 09:00:03    1   Exit

1970-01-01 09:00:01    2   Home
1970-01-01 09:00:02    2   Home // The result
1970-01-01 09:00:03    2   Gift // point de base
1970-01-01 09:00:04    2   Basket

1970-01-01 09:00:01    3   Gift
1970-01-01 09:00:02    3   Home // The result
1970-01-01 09:00:03    3   Gift // point de base
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 // Matched with Home, the result is null
1970-01-01 09:00:02    1   Gift // point de base
1970-01-01 09:00:03    1   Exit

1970-01-01 09:00:01    2   Home // The result
1970-01-01 09:00:02    2   Home // Matched with Home
1970-01-01 09:00:03    2   Gift // point de base
1970-01-01 09:00:04    2   Basket

1970-01-01 09:00:01    3   Gift // The result
1970-01-01 09:00:02    3   Home // Matched with Home
1970-01-01 09:00:03    3   Gift // point de base
1970-01-01 09:00:04    3   Basket
```

**Comportement de `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 // The head can not be point de base because the ref column of the head unmatched with 'ref1'.
 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 // The tail can not be point de base because the ref column of the tail unmatched with 'ref4'.
```

```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 // This row can not be point de base because the ref column unmatched with 'ref3'.
 1970-01-01 09:00:02    1   A      ref3 // point de base
 1970-01-01 09:00:03    1   B      ref2 // The result
 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 // The result
 1970-01-01 09:00:03    1   B      ref2 // point de base
 1970-01-01 09:00:04    1   B      ref1 // This row can not be point de base because the ref column unmatched with 'ref2'.
```
