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

> Documentación de las funciones de agregación paramétricas

# Funciones de agregación paramétricas

Algunas funciones de agregación pueden aceptar no solo columnas de argumentos (usadas para la compresión), sino también un conjunto de parámetros: constantes para la inicialización. La sintaxis utiliza dos pares de paréntesis en lugar de uno. El primero es para los parámetros y el segundo, para los argumentos.

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

Calcula un histograma adaptativo. No garantiza resultados exactos.

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

La función usa [A Streaming Parallel Decision Tree Algorithm](http://jmlr.org/papers/volume11/ben-haim10a/ben-haim10a.pdf). Los límites de los intervalos del histograma se ajustan a medida que entran nuevos datos en la función. En general, los anchos de los intervalos no son iguales.

**Argumentos**

`values` — [Expresión](/es/reference/syntax#expressions) que produce los valores de entrada.

**Parámetros**

`number_of_bins` — Límite superior del número de intervalos en el histograma. La función calcula automáticamente el número de intervalos. Intenta alcanzar el número de intervalos especificado, pero si no lo consigue, usa menos intervalos.

**Valores devueltos**

* [Array](/es/reference/data-types/array) de [Tuplas](/es/reference/data-types/tuple) con el siguiente formato:

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

  * `lower` — Límite inferior del intervalo.
  * `upper` — Límite superior del intervalo.
  * `height` — Altura calculada del intervalo.

**Ejemplo**

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

Puedes ver un histograma con la función [bar](/es/reference/functions/regular-functions/other-functions#bar), por ejemplo:

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

En este caso, debes recordar que no conoces los límites de los intervalos del histograma.

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

Comprueba si la secuencia contiene una cadena de eventos que coincida con el patrón.

**Sintaxis**

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

<Note>
  Los eventos que ocurren en el mismo segundo pueden aparecer en la secuencia en un orden indefinido, lo que afecta al resultado.
</Note>

**Argumentos**

* `timestamp` — Columna que se considera que contiene marcas de tiempo. Los tipos de datos típicos son `Date` y `DateTime`. También puede usar cualquiera de los tipos de datos [UInt](/es/reference/data-types/int-uint) compatibles.

* `cond1`, `cond2` — Condiciones que describen la cadena de eventos. Tipo de dato: `UInt8`. Puede pasar hasta 32 argumentos de condición. La función solo tiene en cuenta los eventos descritos en estas condiciones. Si la secuencia contiene datos que no se describen en ninguna condición, la función los omite.

**Parámetros**

* `pattern` — Cadena del patrón. Consulte [Sintaxis del patrón](#pattern-syntax).

**Valores devueltos**

* 1, si el patrón coincide.
* 0, si el patrón no coincide.

Tipo: `UInt8`.

<div id="pattern-syntax">
  #### Sintaxis del patrón
</div>

* `(?N)` — Coincide con el argumento de condición en la posición `N`. Las condiciones se numeran en el intervalo `[1, 32]`. Por ejemplo, `(?1)` coincide con el argumento pasado al parámetro `cond1`.

* `.*` — Coincide con cualquier número de eventos. No necesita argumentos condicionales para hacer coincidir este elemento del patrón.

* `(?t operator value)` — Establece el tiempo en segundos que debe separar dos eventos. Por ejemplo, el patrón `(?1)(?t>1800)(?2)` coincide con eventos que ocurren con más de 1800 segundos de diferencia entre sí. Entre estos eventos puede haber una cantidad arbitraria de otros eventos. Puede usar los operadores `>=`, `>`, `<`, `<=`, `==`.

**Ejemplos**

Considere los datos de la tabla `t`:

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

Realice la consulta:

```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 función encontró la cadena de eventos en la que el número 2 sigue al número 1. Omitió el número 3 que había entre ambos, porque ese número no está descrito como un evento. Si queremos tener en cuenta este número al buscar la cadena de eventos dada en el ejemplo, debemos definir una condición para él.

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

En este caso, la función no pudo encontrar la cadena de eventos que coincidiera con el patrón, porque el evento número 3 ocurrió entre 1 y 2. Si en este mismo caso comprobáramos la condición para el número 4, la secuencia coincidiría con el patrón.

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

**Véase también**

* [sequenceCount](#sequencecount)

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

Cuenta el número de cadenas de eventos que coinciden con el patrón. La función busca cadenas de eventos que no se solapan. Empieza a buscar la siguiente cadena después de encontrar la cadena actual.

<Note>
  Los eventos que ocurren en el mismo segundo pueden quedar en la secuencia en un orden no definido, lo que afecta al resultado.
</Note>

**Sintaxis**

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

**Argumentos**

* `timestamp` — Columna que se considera que contiene marcas de tiempo. Los tipos de datos típicos son `Date` y `DateTime`. También puede usar cualquiera de los tipos de datos [UInt](/es/reference/data-types/int-uint) compatibles.

* `cond1`, `cond2` — Condiciones que describen la cadena de eventos. Tipo de dato: `UInt8`. Puede proporcionar hasta 32 argumentos de condición. La función solo tiene en cuenta los eventos descritos en estas condiciones. Si la secuencia contiene datos no descritos en ninguna condición, la función los omite.

**Parámetros**

* `pattern` — Cadena con el patrón. Consulte [Sintaxis del patrón](#pattern-syntax).

**Valores devueltos**

* Número de cadenas de eventos no superpuestas que coinciden.

Tipo: `UInt64`.

**Ejemplo**

Considere los datos de la tabla `t`:

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

Cuenta cuántas veces aparece el número 2 después del número 1, con cualquier cantidad de otros números entre ambos:

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

Devuelve las marcas temporales de los eventos de las secuencias de eventos más largas que coincidieron con el patrón.

<Note>
  Los eventos que ocurren en el mismo segundo pueden quedar en la secuencia en un orden indefinido, lo que afecta al resultado.
</Note>

**Sintaxis**

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

**Argumentos**

* `timestamp` — Columna que se considera que contiene datos temporales. Los tipos de datos típicos son `Date` y `DateTime`. También puede usar cualquiera de los tipos de datos [UInt](/es/reference/data-types/int-uint) compatibles.

* `cond1`, `cond2` — Condiciones que describen la cadena de eventos. Tipo de dato: `UInt8`. Puede pasar hasta 32 argumentos de condición. La función solo tiene en cuenta los eventos descritos en estas condiciones. Si la secuencia contiene datos que no se describen en ninguna condición, la función los omite.

**Parámetros**

* `pattern` — Cadena de patrón. Consulte [Sintaxis del patrón](#pattern-syntax).

**Valores devueltos**

* Array de marcas temporales para los argumentos de condición coincidentes (?N) de la cadena de eventos. La posición en el array coincide con la posición del argumento de condición en el patrón.

Tipo: Array.

**Ejemplo**

Considere los datos de la tabla `t`:

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

Devuelve las marcas de tiempo de los eventos de la cadena más larga

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

**Véase también**

* [sequenceMatch](#sequencematch)

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

Busca cadenas de eventos en una ventana de tiempo deslizante y calcula el número máximo de eventos ocurridos dentro de una cadena.

La función opera según el siguiente algoritmo:

* La función busca datos que cumplen la primera condición de la cadena y establece el contador de eventos en 1. Este es el momento en que comienza la ventana deslizante.

* Si los eventos de la cadena ocurren secuencialmente dentro de la ventana, el contador se incrementa. Si la secuencia de eventos se interrumpe, el contador no se incrementa.

* Si los datos contienen varias cadenas de eventos con distintos grados de avance, la función solo devuelve el tamaño de la cadena más larga.

**Sintaxis**

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

**Argumentos**

* `timestamp` — Nombre de la columna que contiene la marca de tiempo. Tipos de datos admitidos: [Date](/es/reference/data-types/date), [DateTime](/es/reference/data-types/datetime) y otros tipos enteros sin signo (ten en cuenta que, aunque `timestamp` admite el tipo `UInt64`, su valor no puede superar el máximo de Int64, que es 2^63 - 1).
* `cond` — Condiciones o datos que describen la cadena de eventos. [UInt8](/es/reference/data-types/int-uint).

**Parámetros**

* `window` — Longitud de la ventana deslizante; es el intervalo de tiempo entre la primera y la última condición. La unidad de `window` depende del propio `timestamp` y puede variar. Se determina mediante la expresión `timestamp of cond1 <= timestamp of cond2 <= ... <= timestamp of condN <= timestamp of cond1 + window`.
* `mode` — Es un argumento opcional. Se puede establecer uno o varios modos.
  * `'strict_deduplication'` — Si la misma condición se cumple en la secuencia de eventos, ese evento repetido interrumpe el procesamiento posterior. Nota: puede comportarse de forma inesperada si varias condiciones se cumplen para el mismo evento.
  * `'strict_order'` — No permite la interposición de otros eventos. Por ejemplo, en el caso de `A->B->D->C`, deja de encontrar `A->B->C` al llegar a `D`, y el nivel máximo de evento es 2.
  * `'strict_increase'` — Aplica las condiciones solo a eventos con marcas de tiempo estrictamente crecientes.
  * `'strict_once'` — Cuenta cada evento solo una vez en la cadena, aunque cumpla la condición varias veces.
  * `'allow_reentry'` — Ignora los eventos que infringen el orden estricto. Por ejemplo, en el caso de A->A->B->C, encuentra A->B->C ignorando la A redundante, y el nivel máximo de evento es 3.

**Valor devuelto**

El número máximo de condiciones activadas consecutivas de la cadena dentro de la ventana temporal deslizante.
Se analizan todas las cadenas de la selección.

Tipo: `Integer`.

**Ejemplo**

Determina si un periodo de tiempo determinado es suficiente para que el usuario seleccione un teléfono y lo compre dos veces en la tienda en línea.

Define la siguiente cadena de eventos:

1. El usuario inició sesión en su cuenta de la tienda (`eventID = 1003`).
2. El usuario busca un teléfono (`eventID = 1007, product = 'phone'`).
3. El usuario realizó un pedido (`eventID = 1009`).
4. El usuario volvió a hacer el pedido (`eventID = 1010`).

Tabla de entrada:

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

Descubra hasta dónde pudo avanzar el usuario `user_id` en la cadena de eventos durante un período entre enero y febrero de 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 │
└───────┴───┘
```

**Ejemplo con el modo allow\_reentry**

Este ejemplo muestra cómo funciona el modo `allow_reentry` con patrones de reingreso de usuarios:

```sql theme={null}
-- Datos de muestra: el usuario visita el checkout -> detalle del producto -> checkout de nuevo -> pago
-- Sin allow_reentry: se detiene en el nivel 2 (página de detalle del producto)
-- Con allow_reentry: alcanza el nivel 4 (finalización del pago)

SELECT
    level,
    count() AS users
FROM
(
    SELECT
        user_id,
        windowFunnel(3600, 'strict_order', 'allow_reentry')(
            timestamp,
            action = 'begin_checkout',      -- Paso 1: Iniciar checkout
            action = 'view_product_detail', -- Paso 2: Ver detalle del producto
            action = 'begin_checkout',      -- Paso 3: Iniciar checkout de nuevo (reentrada)
            action = 'complete_payment'     -- Paso 4: Completar el pago
        ) 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 función acepta como argumentos entre 1 y 32 condiciones de tipo `UInt8` que indican si se ha cumplido una determinada condición para el evento.
Se puede especificar cualquier condición como argumento (como en [WHERE](/es/reference/statements/select/where)).

Las condiciones, excepto la primera, se aplican por pares: el resultado de la segunda será verdadero si la primera y la segunda lo son; el de la tercera, si la primera y la tercera lo son; etc.

**Sintaxis**

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

**Argumentos**

* `cond` — Una expresión que devuelve un resultado `UInt8` (1 o 0).

**Valor devuelto**

Un array de 1 o 0.

* 1 — Se cumplió la condición para el evento.
* 0 — No se cumplió la condición para el evento.

Tipo: `UInt8`.

**Ejemplo**

Veamos un ejemplo del cálculo de la función `retention` para determinar el tráfico del sitio.

**1.** Cree una tabla para este ejemplo.

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

Tabla de entrada:

```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.** Agrupe los usuarios por el ID único `uid` usando la función `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.** Calcule el número total de visitas al sitio por día.

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

Donde:

* `r1`- el número de visitantes únicos que visitaron el sitio en 2020-01-01 (la condición `cond1`).
* `r2`- el número de visitantes únicos que visitaron el sitio durante un período específico entre 2020-01-01 y 2020-01-02 (las condiciones `cond1` y `cond2`).
* `r3`- el número de visitantes únicos que visitaron el sitio durante un período específico en 2020-01-01 y 2020-01-03 (las condiciones `cond1` y `cond3`).

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

Calcula el número de valores distintos del argumento hasta un límite especificado, `N`. Si el número de valores distintos del argumento es mayor que `N`, esta función devuelve `N` + 1; en caso contrario, calcula el valor exacto.

Se recomienda usarla con valores pequeños de `N`, hasta 10. El valor máximo de `N` es 100.

Para el estado de una función de agregación, esta función utiliza una cantidad de memoria igual a 1 + `N` \* el tamaño en bytes de un valor.
Cuando se trabaja con cadenas, esta función almacena un hash no criptográfico de 8 bytes; para las cadenas, el cálculo es aproximado.

Por ejemplo, supongamos que tiene una tabla que registra cada consulta de búsqueda realizada por los usuarios en su sitio web. Cada fila de la tabla representa una única consulta de búsqueda, con columnas para el ID de usuario, la consulta de búsqueda y el timestamp de la consulta. Puede usar `uniqUpTo` para generar un informe que muestre solo las palabras clave que hayan generado al menos 5 usuarios únicos.

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

`uniqUpTo(4)(UserID)` calcula la cantidad de valores únicos de `UserID` para cada `SearchPhrase`, pero solo cuenta hasta 4 valores únicos. Si hay más de 4 valores únicos de `UserID` para un `SearchPhrase`, la función devuelve 5 (4 + 1). La cláusula `HAVING` filtra después los valores de `SearchPhrase` cuyo número de valores únicos de `UserID` es inferior a 5. Esto le dará una lista de palabras clave de búsqueda utilizadas por al menos 5 usuarios únicos.

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

Esta función se comporta igual que [sumMap](/es/reference/functions/aggregate-functions/sumMap), excepto que también acepta como parámetro un array de claves para filtrar. Esto puede resultar especialmente útil cuando se trabaja con una alta cardinalidad de claves.

**Sintaxis**

`sumMapFiltered(keys_to_keep)(keys, values)`

**Parámetros**

* `keys_to_keep`: [Array](/es/reference/data-types/array) de claves para filtrar.
* `keys`: [Array](/es/reference/data-types/array) de claves.
* `values`: [Array](/es/reference/data-types/array) de valores.

**Valor devuelto**

* Devuelve una tupla de dos arrays: claves en orden y valores sumados para las claves correspondientes.

**Ejemplo**

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

Esta función se comporta igual que [sumMap](/es/reference/functions/aggregate-functions/sumMap), salvo que también acepta como parámetro un array de claves por las que filtrar. Esto puede resultar especialmente útil cuando se trabaja con una cardinalidad alta de claves. Se diferencia de la función [sumMapFiltered](#summapfiltered) en que realiza la suma con desbordamiento; es decir, devuelve para la suma el mismo tipo de dato que el tipo de dato del argumento.

**Sintaxis**

`sumMapFilteredWithOverflow(keys_to_keep)(keys, values)`

**Parámetros**

* `keys_to_keep`: [Array](/es/reference/data-types/array) de claves por las que filtrar.
* `keys`: [Array](/es/reference/data-types/array) de claves.
* `values`: [Array](/es/reference/data-types/array) de valores.

**Valor devuelto**

* Devuelve una tupla de dos arrays: las claves en orden y los valores sumados para las claves correspondientes.

**Ejemplo**

En este ejemplo, creamos una tabla `sum_map`, insertamos algunos datos en ella y luego usamos tanto `sumMapFilteredWithOverflow` como `sumMapFiltered`, junto con la función `toTypeName`, para comparar el resultado. Como `requests` era de tipo `UInt8` en la tabla creada, `sumMapFiltered` ha promovido el tipo de los valores sumados a `UInt64` para evitar el desbordamiento, mientras que `sumMapFilteredWithOverflow` ha mantenido el tipo como `UInt8`, que no es lo bastante grande como para almacenar el resultado; es decir, se ha producido un desbordamiento.

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

Devuelve el valor del siguiente evento que coincide con una cadena de eventos.

*Función experimental. Para habilitarla, `SET allow_experimental_funnel_functions = 1`.*

**Sintaxis**

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

**Parámetros**

* `direction` — Se utiliza para indicar la dirección.
  * forward — Hacia adelante.
  * backward — Hacia atrás.

* `base` — Se utiliza para establecer el punto base.
  * head — Establece el punto base en el primer evento.
  * tail — Establece el punto base en el último evento.
  * first\_match — Establece el punto base en el primer `event1` que coincide.
  * last\_match — Establece el punto base en el último `event1` que coincide.

**Argumentos**

* `timestamp` — Nombre de la columna que contiene la marca temporal. Tipos de datos compatibles: [Date](/es/reference/data-types/date), [DateTime](/es/reference/data-types/datetime) y otros tipos de enteros sin signo.
* `event_column` — Nombre de la columna que contiene el valor del siguiente evento que se va a devolver. Tipos de datos compatibles: [String](/es/reference/data-types/string) y [Nullable(String)](/es/reference/data-types/nullable).
* `base_condition` — Condición que debe cumplir el punto base.
* `event1`, `event2`, ... — Condiciones que describen la cadena de eventos. [UInt8](/es/reference/data-types/int-uint).

**Valores devueltos**

* `event_column[next_index]` — Si el patrón coincide y existe un valor siguiente.
* `NULL` - Si el patrón no coincide o no existe un valor siguiente.

Tipo: [Nullable(String)](/es/reference/data-types/nullable).

**Ejemplo**

Puede utilizarse cuando los eventos son A->B->C->D->E y se desea conocer el evento que sigue a B->C, que es D.

La instrucción de consulta que busca el evento que sigue a 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         │
└────┴───────────┘
```

**Comportamiento de `forward` y `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 // Punto base, coincide con Home
 1970-01-01 09:00:02    1   Gift // Coincide con Gift
 1970-01-01 09:00:03    1   Exit // El resultado

 1970-01-01 09:00:01    2   Home // Punto base, coincide con Home
 1970-01-01 09:00:02    2   Home // No coincide con 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 // Punto base, no coincide con 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
```

**Comportamiento de `backward` y `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 // Punto base, no coincide con Basket

1970-01-01 09:00:01    2   Home
1970-01-01 09:00:02    2   Home // El resultado
1970-01-01 09:00:03    2   Gift // Coincide con Gift
1970-01-01 09:00:04    2   Basket // Punto base, coincide con Basket

1970-01-01 09:00:01    3   Gift
1970-01-01 09:00:02    3   Home // El resultado
1970-01-01 09:00:03    3   Gift // Punto base, coincide con Gift
1970-01-01 09:00:04    3   Basket // Punto base, coincide con Basket
```

**Comportamiento de `forward` y `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 // Punto base
1970-01-01 09:00:03    1   Exit // El resultado

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

1970-01-01 09:00:01    3   Gift // Punto base
1970-01-01 09:00:02    3   Home // El resultado
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 // Punto base
1970-01-01 09:00:03    1   Exit // No coincide con 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 // Punto base
1970-01-01 09:00:04    2   Basket // No coincide con Home

1970-01-01 09:00:01    3   Gift // Punto base
1970-01-01 09:00:02    3   Home // Coincide con Home
1970-01-01 09:00:03    3   Gift // El resultado
1970-01-01 09:00:04    3   Basket
```

**Comportamiento de `backward` y `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 // El resultado
1970-01-01 09:00:02    1   Gift // Punto 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 // El resultado
1970-01-01 09:00:03    2   Gift // Punto 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 // El resultado
1970-01-01 09:00:03    3   Gift // Punto 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 // Coincide con Home, el resultado es null
1970-01-01 09:00:02    1   Gift // Punto base
1970-01-01 09:00:03    1   Exit

1970-01-01 09:00:01    2   Home // El resultado
1970-01-01 09:00:02    2   Home // Coincide con Home
1970-01-01 09:00:03    2   Gift // Punto base
1970-01-01 09:00:04    2   Basket

1970-01-01 09:00:01    3   Gift // El resultado
1970-01-01 09:00:02    3   Home // Coincide con Home
1970-01-01 09:00:03    3   Gift // Punto base
1970-01-01 09:00:04    3   Basket
```

**Comportamiento 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 // El head no puede ser el punto base porque la columna ref del head no coincide con '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 // El tail no puede ser el punto base porque la columna ref del tail no coincide con '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 // Esta fila no puede ser el punto base porque la columna ref no coincide con 'ref3'.
 1970-01-01 09:00:02    1   A      ref3 // Punto base
 1970-01-01 09:00:03    1   B      ref2 // El resultado
 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 // El resultado
 1970-01-01 09:00:03    1   B      ref2 // Punto base
 1970-01-01 09:00:04    1   B      ref1 // Esta fila no puede ser punto base porque la columna ref no coincide con 'ref2'.
```
