Агрегатные функции#
Агрегатные функции позволяют получить результирующее значение на основе значений колонок из нескольких записей.
Обработка NULL#
За исключением max_by(), min_by(), array_agg() и approx_distinct(), агрегатные функции игнорируют значения NULL при расчете финального значения.
Данные функции возвращают NULL, если все агрегированные значения были NULL.
При необходимости вы можете использовать функцию COALESCE для преобразования значения NULL в ноль.
Сортировка записей#
Результат некоторых агрегатных функций, таких как array_agg(), зависит от порядка агрегируемых записей.
Порядок записей можно задать с помощью выражения ORDER BY:
array_agg(x ORDER BY y DESC)
array_agg(x ORDER BY x, y, z)
Фильтрация записей#
Ключевое слово FILTER можно использовать для игнорирования части записей в процессе агрегации.
aggregate_function(...) FILTER (WHERE <condition>)
Распространенным примером использования FILTER является удаление NULL значений для функции array_agg:
SELECT array_agg(name) FILTER (WHERE name IS NOT NULL)
FROM region;
Рассмотрим другой пример на основе набора данных «Ирисы Фишера», который содержит данные о 150 экземплярах ириса, включая их вид (setosa - щетинистый, virginica - виргинский, versicolor - разноцветный), а также отдельные характеристики каждого цветка.
Следующий запрос возвращает количество ирисов каждого вида:
SELECT species, count(*) AS count
FROM iris
GROUP BY species;
species | count
-----------+-------
setosa | 50
virginica | 50
versicolor | 50
Предположим, что мы хотим посчитать количество ирисов с определенной характеристикой (petal_length_cm > 4) в каждой группе.
Если мы применим данное условие в качестве предиката WHERE, запись с видом setosa не будет возвращена, так как ни один конкретный цветок данного вида не подходит под условие:
SELECT species,
count(*) AS count
FROM iris
WHERE petal_length_cm > 4
GROUP BY species;
species | count
-----------+-------
virginica | 50
versicolor | 34
Если же мы передадим условие в качестве фильтра агрегатной функции, запрос вернет записи для каждого вида, включая setosa:
SELECT species,
count(*) FILTER (where petal_length_cm > 4) AS count
FROM iris
GROUP BY species;
species | count
-----------+-------
virginica | 50
setosa | 0
versicolor | 34
Общие функции#
- any_value(x) [same as input]#
Возвращает произвольное ненулевое значение, выбранное среди значений группы.
- arbitrary(x) [same as input]#
Псевдоним
any_value().
- array_agg(x) array<[same as input]>#
Возвращает массив, созданный из входных элементов
x. ЗначенияNULLбудут включены в результат.
- avg(x) double#
Возвращает среднее арифметическое значение всех входных значений.
- avg(time interval type) time interval type
Возвращает среднюю длину интервала всех входных значений.
- bool_and(boolean) boolean#
Возвращает
TRUE, если каждое входное значение равноTRUE, в противном случаеFALSE.
- bool_or(boolean) boolean#
Возвращает
TRUE, если какое-либо входное значение равноTRUE, в противном случаеFALSE.
- checksum(x) varbinary#
Возвращает контрольную сумму, рассчитанную на основе входных значений. Значение контрольной суммы не зависит от порядка входных значений.
- count(*) bigint#
Возвращает количество входных записей. Запись будет учтена, даже если она содержит только
NULLзначения.
- count(x) bigint
Возвращает количество входных значений отличных от
NULL.
- count_if(x) bigint#
Возвращает количество входных значений
TRUE. Эквивалентнаcount(CASE WHEN x THEN 1 END).
- every(boolean) boolean#
Псевдоним
bool_and().
- geometric_mean(x) double#
Возвращает среднее геометрическое всех входных значений.
- listagg(x, separator) varchar#
Возвращает объединенные входные значения, разделенные
separator. ЗначенияNULLне будут включены в результат.Синтаксис:
LISTAGG( expression [, separator] [ON OVERFLOW overflow_behaviour]) WITHIN GROUP (ORDER BY sort_item, [...]) [FILTER (WHERE condition)]Если
separatorне указан, в качестве разделителя будет использована пустая строка.Пример:
SELECT listagg(value, ',') WITHIN GROUP (ORDER BY value) csv_value FROM (VALUES 'a', 'c', 'b') t(value);
csv_value ----------- 'a,b,c'
Поведение по умолчанию вызывает ошибку в случае, если длина результирующей строки превышает
1048576байт:SELECT listagg(value, ',' ON OVERFLOW ERROR) WITHIN GROUP (ORDER BY value) csv_value FROM (VALUES 'a', 'b', 'c') t(value);
Существует возможность обрезать вывод
WITH COUNTилиWITHOUT COUNTдля пропущенных ненулевых значений в случае, если длина вывода функции превышает1048576байт:SELECT listagg(value, ',' ON OVERFLOW TRUNCATE '.....' WITH COUNT) WITHIN GROUP (ORDER BY value) FROM (VALUES 'a', 'b', 'c') t(value);
По умолчанию в качестве аргумента
TRUNCATEбудет использована строка'...'.ORDER BY может быть применен к колонкам или выражениям, отличным от аргумента
LISTAGG:SELECT id, listagg(value, ',') WITHIN GROUP (ORDER BY o) csv_value FROM (VALUES (100, 1, 'a'), (200, 3, 'c'), (200, 2, 'b') ) t(id, o, value) GROUP BY id ORDER BY id;
id | csv_value -----+----------- 100 | a 200 | b,c
Данная функция поддерживает фильтрацию во время агрегации.
Следующий запрос
SELECT country, listagg(city, ',') WITHIN GROUP (ORDER BY population DESC) FILTER (WHERE population >= 10_000_000) megacities FROM (VALUES ('India', 'Bangalore', 13_700_000), ('India', 'Chennai', 12_200_000), ('India', 'Ranchi', 1_547_000), ('Austria', 'Vienna', 1_897_000), ('Poland', 'Warsaw', 1_765_000) ) t(country, city, population) GROUP BY country ORDER BY country;
дает результат:
country | megacities ---------+------------------- Austria | NULL India | Bangalore,Chennai Poland | NULL
Текущая реализация функции
LISTAGGне поддерживает фреймы оконных функций.
- max(x) [same as input]#
Возвращает максимальное значение всех входных значений.
- max(x, n) array<[same as x]>
Возвращает
nнаибольших значений из всех входных значенийx.
- max_by(x, y) [same as x]#
Возвращает значение
x, связанное с наибольшим значениемy. Если наибольшее значениеyприсутствует в нескольких записях, будет возвращено значениеxодной из данных записей.
- max_by(x, y, n) array<[same as x]>
Возвращает
nзначенийx, связанных сnнаибольших значенийyв порядке убыванияy.
- min(x) [same as input]#
Возвращает минимальное значение всех входных значений.
- min(x, n) array<[same as x]>
Возвращает
nнаименьших значений из всех входных значенийx.
- min_by(x, y) [same as x]#
Возвращает значение
x, связанное с наименьшим значениемy. Если наименьшее значениеyприсутствует в нескольких записях, будет возвращено значениеxодной из данных записей.
- min_by(x, y, n) array<[same as x]>
Возвращает
nзначенийx, связанных сnнаименьших значенийyв порядке возрастанияy.
- sum(x) [same as input]#
Возвращает сумму входных значений.
Побитовые функции#
- bitwise_and_agg(x) bigint#
Возвращает побитовое AND всех входных значений, отличных от NULL. Возвращает NULL, если все значения группы равны NULL или группа пуста.
- bitwise_or_agg(x) bigint#
Возвращает побитовое OR всех входных значений, отличных от NULL. Возвращает NULL, если все значения группы равны NULL или группа пуста.
- bitwise_xor_agg(x) bigint#
Возвращает побитовое XOR всех входных значений, отличных от NULL. Возвращает NULL, если все значения группы равны NULL или группа пуста.
Функции, возвращающие словари (MAP)#
- histogram(x) map<K,bigint>#
Возвращает словарь, содержащий количество повторений каждого входного значения.
- map_agg(key, value) map<K,V>#
Возвращает словарь, созданный из входных пар
key/value.
- map_union(x(K, V)) map<K,V>#
Объединяет все входные словари. Если ключ найден в нескольких словарях, его значение в результирующем словаре будет равно значению ключа в одном из входных словарей.
Рассмотрим функцию
histogram, которая создает несколько словарей из набора данных «Ирисы Фишера»:SELECT histogram(floor(petal_length_cm)) petal_data FROM memory.default.iris GROUP BY species;
petal_data ------------ {4.0=6, 5.0=33, 6.0=11} {4.0=37, 5.0=2, 3.0=11} {1.0=50}Вы можете объединить результирующие словари, используя функцию
map_union:SELECT map_union(petal_data) petal_data_union FROM ( SELECT histogram(floor(petal_length_cm)) petal_data FROM memory.default.iris GROUP BY species );
petal_data_union ------------------ {4.0=6, 5.0=2, 6.0=11, 1.0=50, 3.0=11}
- multimap_agg(key, value) map<K,array(V)>#
Возвращает мультисловарь (multimap), созданный из входных пар
key/value.
Приближенные функции#
- approx_distinct(x) bigint#
Возвращает приблизительное количество уникальных входных значений. Является приблизительным эквивалентом
count(DISTINCT x).Функция выдает стандартную ошибку 2,35% и не гарантирует верхнюю границу ошибки.
- approx_distinct(x, e) bigint
Возвращает приблизительное количество уникальных входных значений. Является приблизительным эквивалентом
count(DISTINCT x).Функция выдает стандартную ошибку
eи не гарантирует верхнюю границу ошибки. Текущая реализация этой функции требует, чтобы значениеeнаходилось в диапазоне[0.0040625, 0.26000].
- approx_most_frequent(buckets, value, capacity) map<[same as value], bigint>#
Приблизительно вычисляет наиболее часто встречающиеся значения среди входных значений
value. Результатом работы функции является словарь размером не болееbuckets. Для формирования словаря будет использовано не болееcapacityвходных значений. Увеличение значенияcapacityповышает точность, но может увеличить потребление памяти.bucketsиcapacityдолжны иметь типbigint.valueможет быть числовым или строковым типом.Функция использует алгоритм, предложенный в статье Efficient Computation of Frequent and Top-k Elements in Data Streams by A. Metwalley, D. Agrawl and A. Abbadi.
- approx_percentile(x, percentage) [same as x]#
Возвращает приблизительный процентиль для всех входных значений
xв заданном процентеpercentage. Значениеpercentageдолжно быть в диапазоне от нуля до единицы.
- approx_percentile(x, percentages) array<[same as x]>
Возвращает приблизительный процентиль для всех входных значений
xдля каждого из указанных значений процентовpercentages. Значение каждого элемента массиваpercentagesдолжно быть в диапазоне от нуля до единицы.
- approx_percentile(x, w, percentage) [same as x]
Возвращает приблизительный процентиль для всех входных значений
xв заданном процентеpercentage, используя вес элементаw. Значениеpercentageдолжно быть в диапазоне от нуля до единицы. Значениеwдолжно быть больше или равно единицы.
- approx_percentile(x, w, percentages) array<[same as x]>
Возвращает приблизительный процентиль для всех входных значений
xдля каждого из указанных значений процентовpercentages, используя вес элементаw. Значение каждого элемента массиваpercentagesдолжно быть в диапазоне от нуля до единицы. Значениеwдолжно быть больше или равно единицы.
- approx_set(x) HyperLogLog
- merge(x) HyperLogLog
- merge(qdigest(T)) -> qdigest(T)
- merge(tdigest) tdigest
См. T-Digest functions.
- numeric_histogram(buckets, value) map<double, double>
Вычисляет приблизительную гистограмму с количеством сегментов до
bucketsдля всехvalue. Эта функция эквивалентна вариантуnumeric_histogram(), который принимаетweightс весом каждого элемента1.
- numeric_histogram(buckets, value, weight) map<double, double>#
Вычисляет приблизительную гистограмму с количеством сегментов до
bucketsдля всехvalueс весом элементаweight. Алгоритм основан на:Yael Ben-Haim and Elad Tom-Tov, "A streaming parallel decision tree algorithm", J. Machine Learning Research 11 (2010), pp. 849--872.
bucketsдолжен бытьbigint.valueиweightдолжны быть числовыми.
- qdigest_agg(x) -> qdigest([same as x])
- qdigest_agg(x, w) -> qdigest([same as x])
- qdigest_agg(x, w, accuracy) -> qdigest([same as x])
- tdigest_agg(x) tdigest
См. T-Digest functions.
- tdigest_agg(x, w) tdigest
См. T-Digest functions.
Статистические функции#
- corr(y, x) double#
Возвращает коэффициент Пирсона корреляции числовых пар входных значений.
- covar_pop(y, x) double#
Возвращает ковариацию генеральной совокупности числовых пар входных значений.
- covar_samp(y, x) double#
Возвращает ковариацию выборки числовых пар входных значений.
- kurtosis(x) double#
Возвращает kurtosis входных значений, рассчитанный по формуле:
kurtosis(x) = n(n+1)/((n-1)(n-2)(n-3))sum[(x_i-mean)^4]/stddev(x)^4-3(n-1)^2/((n-2)(n-3))
- regr_intercept(y, x) double#
Возвращает перехват линии линейной регрессии входных значений.
y- зависимое значение,x- независимое значение.
- regr_slope(y, x) double#
Возвращает наклон линии линейной регрессии входных значений.
y- зависимое значение,x- независимое значение.
- stddev(x) double#
Псевдоним
stddev_samp().
- stddev_pop(x) double#
Возвращает стандартное отклонение входных значений.
- stddev_samp(x) double#
Возвращает выборочное стандартное отклонение входных значений.
- variance(x) double#
Псевдоним
var_samp().
- var_pop(x) double#
Возвращает дисперсию входных значений.
- var_samp(x) double#
Возвращает выборочную дисперсию входных значений.
Lambda-функции#
- reduce_agg(inputValue T, initialState S, inputFunction(S, T, S), combineFunction(S, S, S)) S#
Позволяет выполнить агрегацию на основе произвольных функций.
inputValueопределяет значение записи, передаваемое в функцию.initialStateопределяет начальное состояние функции. Для каждой записи будет вызвана функцияinputFunction, которая принимает текущее состояние функции иinputValueзаписи и возвращает новое состояние функции.В процессе расчета агрегата CedrusData может сформировать несколько независимых промежуточных состояний, полученных из непересекающихся наборов записей. Формирование финального результата происходит путем последовательного объединения всех промежуточных состояний с помощью функции
combineFunction.Пример:
SELECT id, reduce_agg(value, 0, (a, b) -> a + b, (a, b) -> a + b) FROM ( VALUES (1, 3), (1, 4), (1, 5), (2, 6), (2, 7) ) AS t(id, value) GROUP BY id; -- (1, 12) -- (2, 13) SELECT id, reduce_agg(value, 1, (a, b) -> a * b, (a, b) -> a * b) FROM ( VALUES (1, 3), (1, 4), (1, 5), (2, 6), (2, 7) ) AS t(id, value) GROUP BY id; -- (1, 60) -- (2, 42)
Допустимые типы состояния: