> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> Selects the time series with the k smallest values at each grid step.

# timeSeriesBottomKMasks

<h2 id="timeSeriesBottomKMasks">
  timeSeriesBottomKMasks
</h2>

Introduced in: v26.8.0

Selects the time series with the k smallest values at each time step of a time grid.

Each input row is one time series: `key` identifies the series and `values` contains its values aligned to a common
time grid, so the `values` arrays of all rows must have the same size. At each time step, the series with the k smallest
non-NULL values at that step are selected (NaN is considered greater than any other value). Value ties are broken by
preferring the series with the smaller `key`.

This function implements the `bottomk()` aggregation operator of PromQL and keeps only one bounded heap of size `k` per
time step, so its state size does not depend on the number of aggregated series.

<Note>
  This function is in private preview, enable it by setting `enable_time_series_aggregate_functions = 1`.
</Note>

**Syntax**

```sql theme={null}
timeSeriesBottomKMasks(k, key, values)
```

**Arguments**

* `k` — How many series to select at each time step, either one value for all time steps or an array with one value per time step. Must be the same for all rows. [`UInt*`](/docs/reference/data-types/int-uint) or [`Array(UInt*)`](/docs/reference/data-types/array)
* `key` — Identifier of the time series. [`UInt64`](/docs/reference/data-types/int-uint)
* `values` — Values of the time series aligned to the time grid, one element per time step. [`Array(Nullable(Float32))`](/docs/reference/data-types/array) or [`Array(Nullable(Float64))`](/docs/reference/data-types/array) or [`Array(Float32)`](/docs/reference/data-types/array) or [`Array(Float64)`](/docs/reference/data-types/array)

**Returned value**

Returns the selected series in the order of ascending `key`, each together with its per-step mask: `steps_mask[t] = 1` if the series is selected at time step `t`. Series which are selected at no time step are not returned. [`Array(Tuple(key UInt64, steps_mask Array(UInt8)))`](/docs/reference/data-types/array)

**Examples**

**Selecting the 2 smallest series per time step**

```sql title=Query theme={null}
SET enable_time_series_aggregate_functions = 1;
WITH [(1, [10., 1., NULL]), (2, [20., 2., 2.]), (3, [30., NULL, 1.])]::Array(Tuple(UInt64, Array(Nullable(Float64)))) AS series
SELECT timeSeriesBottomKMasks(2, s.1, s.2)
FROM (SELECT arrayJoin(series) AS s);
```

```response title=Response theme={null}
[(1,[1,1,0]),(2,[1,1,1]),(3,[0,0,1])]
```
