Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Агрегатные функции

Агрегатные функции работают обычным образом, как и ожидают специалисты по базам данных.

ClickHouse также поддерживает:

Обработка NULL

При агрегации все аргументы со значением NULL пропускаются. Если у агрегации несколько аргументов, игнорируется любая строка, в которой один или несколько из них имеют значение NULL.

Из этого правила есть исключение: функции first_value, last_value и их псевдонимы (any и anyLast соответственно), если за ними следует модификатор RESPECT NULLS. Например, FIRST_VALUE(b) RESPECT NULLS.

Примеры:

Рассмотрим следующую таблицу:

┌─x─┬────y─┐
│ 1 │    2 │
│ 2 │ ᴺᵁᴸᴸ │
│ 3 │    2 │
│ 3 │    3 │
│ 3 │ ᴺᵁᴸᴸ │
└───┴──────┘

Допустим, вам нужно суммировать значения в столбце y:

SELECT sum(y) FROM t_null_big
┌─sum(y)─┐
│      7 │
└────────┘

Теперь вы можете использовать функцию groupArray, чтобы создать массив из столбца y:

SELECT groupArray(y) FROM t_null_big
┌─groupArray(y)─┐
│ [2,2,3]       │
└───────────────┘

groupArray не включает NULL в результирующий массив.

Вы можете использовать COALESCE, чтобы заменить NULL на значение, подходящее для вашего сценария использования. Например, avg(COALESCE(column, 0)) будет использовать значение столбца при агрегации или ноль, если это NULL:

SELECT
    avg(y),
    avg(coalesce(y, 0))
FROM t_null_big
┌─────────────avg(y)─┬─avg(coalesce(y, 0))─┐
│ 2.3333333333333335 │                 1.4 │
└────────────────────┴─────────────────────┘

Также можно использовать Tuple, чтобы обойти поведение, связанное с пропуском NULL. Tuple, содержащий только значение NULL, сам не является NULL, поэтому агрегатные функции не будут пропускать эту строку из-за этого значения NULL.

SELECT
    groupArray(y),
    groupArray(tuple(y)).1
FROM t_null_big;

Обратите внимание, что агрегации пропускаются, если столбцы используются в качестве аргументов агрегатной функции. Например, count без параметров (count()) или с константными параметрами (count(1)) будет подсчитывать все строки в блоке (независимо от значения столбца GROUP BY, так как он не является аргументом), тогда как count(column) вернет только количество строк, в которых column не равно NULL.

SELECT
    v,
    count(1),
    count(v)
FROM
(
    SELECT if(number < 10, NULL, number % 3) AS v
    FROM numbers(15)
)
GROUP BY v

И вот пример first_value с RESPECT NULLS, где видно, что входные значения NULL учитываются и возвращается первое прочитанное значение — независимо от того, равно оно NULL или нет:

SELECT
    col || '_' || ((col + 1) * 5 - 1) AS range,
    first_value(odd_or_null) AS first,
    first_value(odd_or_null) IGNORE NULLS as first_ignore_null,
    first_value(odd_or_null) RESPECT NULLS as first_respect_nulls
FROM
(
    SELECT
        intDiv(number, 5) AS col,
        if(number % 2 == 0, NULL, number) AS odd_or_null
    FROM numbers(15)
)
GROUP BY col
ORDER BY col

Navigation