Комбинаторы агрегатных функций
К имени агрегатной функции можно добавить суффикс. Это изменяет способ работы агрегатной функции.
-If
Суффикс -If можно добавить к имени любой агрегатной функции. В этом случае агрегатная функция принимает дополнительный аргумент — условие (тип Uint8). Агрегатная функция обрабатывает только те строки, которые вызывают это условие. Если условие не было выполнено хотя бы раз, оно возвращает значение по умолчанию (обычно нули или пустые строки).
Примеры: sumIf(column, cond)
, countIf(cond)
, avgIf(x, cond)
, quantilesTimingIf(level1, level2)(x, cond)
, argMinIf(arg, val, cond)
и так далее.
С помощью условных агрегатных функций можно одновременно вычислять агрегаты для нескольких условий, не используя подзапросы и JOIN
. Например, условные агрегатные функции могут быть использованы для реализации функциональности сравнения сегментов.
-Array
Суффикс -Array можно добавить к любой агрегатной функции. В этом случае агрегатная функция принимает аргументы типа 'Array(T)' (массивы) вместо аргументов типа 'T'. Если агрегатная функция принимает несколько аргументов, это должны быть массивы одинаковой длины. При обработке массивов агрегатная функция работает как оригинальная агрегатная функция для всех элементов массива.
Пример 1: sumArray(arr)
— суммирует все элементы всех массивов 'arr'. В этом примере это можно было бы записать проще: sum(arraySum(arr))
.
Пример 2: uniqArray(arr)
— считает количество уникальных элементов во всех массивах 'arr'. Это можно было бы сделать и более простым способом: uniq(arrayJoin(arr))
, но не всегда возможно добавить 'arrayJoin' в запрос.
-If и -Array могут быть комбинированы. Однако 'Array' должен идти первым, затем 'If'. Примеры: uniqArrayIf(arr, cond)
, quantilesTimingArrayIf(level1, level2)(arr, cond)
. Из-за этого порядка аргумент 'cond' не будет массивом.
-Map
Суффикс -Map можно добавить к любой агрегатной функции. Это создаст агрегатную функцию, которая принимает аргумент типа Map и агрегирует значения каждого ключа карты отдельно, используя указанную агрегатную функцию. Результат также будет типа Map.
Пример
-SimpleState
Если вы применяете этот комбинатор, агрегатная функция возвращает то же значение, но с другим типом. Это SimpleAggregateFunction(...), которую можно хранить в таблице для работы с таблицами AggregatingMergeTree.
Синтаксис
Аргументы
x
— Параметры агрегатной функции.
Возвращаемые значения
Значение агрегатной функции с типом SimpleAggregateFunction(...)
.
Пример
Запрос:
Результат:
-State
Если вы применяете этот комбинатор, агрегатная функция не возвращает результирующее значение (например, количество уникальных значений для функции uniq), а промежуточное состояние агрегации (для uniq
это хеш-таблица для вычисления количества уникальных значений). Это AggregateFunction(...)
, которую можно использовать для дальнейшей обработки или хранить в таблице для завершения агрегации позже.
Пожалуйста, обратите внимание, что -MapState не является инвариантом для одних и тех же данных, поскольку порядок данных в промежуточном состоянии может изменяться, хоть это и не влияет на прием этих данных.
Для работы с этими состояниями используйте:
- AggregatingMergeTree движок таблиц.
- finalizeAggregation функцию.
- runningAccumulate функцию.
- -Merge комбинатор.
- -MergeState комбинатор.
-Merge
Если вы применяете этот комбинатор, агрегатная функция принимает промежуточное состояние агрегации в качестве аргумента, комбинирует состояния для завершения агрегации и возвращает результирующее значение.
-MergeState
Комбинирует промежуточные состояния агрегации так же, как и комбинатор -Merge. Однако он не возвращает результирующее значение, а промежуточное состояние агрегации, аналогично комбинатору -State.
-ForEach
Преобразует агрегатную функцию для таблиц в агрегатную функцию для массивов, которая агрегирует соответствующие элементы массива и возвращает массив результатов. Например, sumForEach
для массивов [1, 2]
, [3, 4, 5]
и [6, 7]
возвращает результат [10, 13, 5]
, после сложения соответствующих элементов массива.
-Distinct
Каждая уникальная комбинация аргументов будет агрегирована только один раз. Повторяющиеся значения игнорируются.
Примеры: sum(DISTINCT x)
(или sumDistinct(x)
), groupArray(DISTINCT x)
(или groupArrayDistinct(x)
), corrStable(DISTINCT x, y)
(или corrStableDistinct(x, y)
) и так далее.
-OrDefault
Изменяет поведение агрегатной функции.
Если у агрегатной функции нет входных значений, с этим комбинатором она возвращает значение по умолчанию для своего типа возвращаемых данных. Применяется к агрегатным функциям, которые могут принимать пустые входные данные.
-OrDefault
может быть использован с другими комбинаторами.
Синтаксис
Аргументы
x
— Параметры агрегатной функции.
Возвращаемые значения
Возвращает значение по умолчанию типа возвращаемых данных агрегатной функции, если нечего агрегировать.
Тип зависит от используемой агрегатной функции.
Пример
Запрос:
Результат:
Также -OrDefault
может использоваться с другими комбинаторами. Он полезен, когда агрегатная функция не принимает пустые входные данные.
Запрос:
Результат:
-OrNull
Изменяет поведение агрегатной функции.
Этот комбинатор преобразует результат агрегатной функции в тип данных Nullable. Если у агрегатной функции нет значений для вычисления, она возвращает NULL.
-OrNull
может быть использован с другими комбинаторами.
Синтаксис
Аргументы
x
— Параметры агрегатной функции.
Возвращаемые значения
- Результат агрегатной функции, преобразованный в тип
Nullable
. NULL
, если нечего агрегировать.
Тип: Nullable(тип возвращаемого значения агрегатной функции)
.
Пример
Добавьте -orNull
в конец агрегатной функции.
Запрос:
Результат:
Также -OrNull
может быть использован с другими комбинаторами. Он полезен в случаях, когда агрегатная функция не принимает пустые входные данные.
Запрос:
Результат:
-Resample
Позволяет разбивать данные на группы, а затем отдельно агрегирует данные в этих группах. Группы создаются путем разбивания значений из одного столбца на интервалы.
Аргументы
start
— Начальное значение всего необходимого интервала для значенийresampling_key
.stop
— Конечное значение всего необходимого интервала для значенийresampling_key
. Весь интервал не включает значениеstop
[start, stop)
.step
— Шаг для разделения всего интервала на подинтервалы. ФункцияaggFunction
выполняется для каждого из этих подинтервалов независимо.resampling_key
— Столбец, значения которого используются для разделения данных на интервалы.aggFunction_params
— ПараметрыaggFunction
.
Возвращаемые значения
- Массив результатов
aggFunction
для каждого подинтервала.
Пример
Рассмотрим таблицу people
с следующими данными:
Давайте получим имена людей, чей возраст попадает в интервалы [30,60)
и [60,75)
. Поскольку мы используем целочисленное представление возраста, мы получаем возраст в интервалах [30, 59]
и [60,74]
.
Чтобы агрегировать имена в массив, мы используем агрегатную функцию groupArray. Она принимает один аргумент. В нашем случае это столбец name
. Функция должна использовать groupArrayResample
, чтобы агрегировать имена по возрасту. Для определения необходимых интервалов передаем в функцию groupArrayResample
аргументы 30, 75, 30
.
Рассмотрим результаты.
John
не попадает в выборку, потому что он слишком молод. Остальные люди распределены согласно указанным возрастным интервалам.
Теперь давайте подсчитаем общее количество людей и их среднюю зарплату в указанных возрастных интервалах.
-ArgMin
Суффикс -ArgMin можно добавить к имени любой агрегатной функции. В этом случае агрегатная функция принимает дополнительный аргумент, который должен быть любым сравнимым выражением. Агрегатная функция обрабатывает только те строки, у которых минимальное значение для указанного дополнительного выражения.
Примеры: sumArgMin(column, expr)
, countArgMin(expr)
, avgArgMin(x, expr)
и так далее.
-ArgMax
Похоже на суффикс -ArgMin, но обрабатывает только те строки, у которых максимальное значение для указанного дополнительного выражения.