聚合函数

概述

聚合函数对一组值进行操作以计算单个结果。

除了 count(), count_if(), max_by(), min_by()approx_distinct() 之外,所有这些聚合函数都忽略空值,并且在没有输入行或所有值都为空时返回空值。例如,sum() 返回空值而不是零,而 avg() 不包括空值在计数中。可以使

某些聚合函数,例如 array_agg(),会根据输入值的顺序产生不同的结果。此顺序可以通过在聚合函数内编写一个 ORDER BY 子句 来指定。

array_agg(x ORDER BY y DESC)
array_agg(x ORDER BY x, y, z)

通用聚合函数

any_value(x) -> [与 输入 相同]()

这是 arbitrary() 的别名。

arbitrary(x) -> [与 输入 相同]()

返回 x 的任意非空值(如果存在)。

array_agg(x) -> array<[与 输入 相同]>()

返回由输入 x 元素创建的数组。

avg(x) -> double()

返回所有输入值的平均值(算术平均值)。

avg(时间 间隔 类型) -> 时间 间隔 类型()

返回所有输入值的平均间隔长度。

bool_and(布尔值) -> 布尔值()

如果所有输入值均为 TRUE,则返回 TRUE,否则返回 FALSE

bool_or(boolean) -> boolean()

如果任何输入值为 TRUE,则返回 TRUE,否则返回 FALSE

checksum(x) -> varbinary()

返回给定值的与顺序无关的校验和。

count(*) -> bigint()

返回输入行的数量。

count(x) -> bigint()

返回非空输入值的个数。

count_if(x) -> bigint()

返回 TRUE 输入值的个数。此函数等效于 count(CASE WHEN x THEN 1 END)

every(boolean) -> boolean()

这是 bool_and() 的别名。

geometric_mean(bigint) -> double()
geometric_mean(double) -> double()
geometric_mean(real) -> real()

返回所有输入值的 几何平均数

max_by(x, y) -> [same as x]()

返回与所有输入值中 y 的最大值相关联的 x 值。

max_by(x, y, n) -> array<[same as x]>()

返回与所有输入值中 y 的前 n 个最大值相关联的 nx 值,按 y 的降序排列。

min_by(x, y) -> [same as x]()

返回与所有输入值中 y 的最小值相关联的 x 值。

min_by(x, y, n) -> array<[same as x]>()

返回与所有输入值中 y 的前 n 个最小值相关联的 nx 值,按 y 的升序排列。

max(x) -> [same as input]()

返回所有输入值的 最大值。

max(x, n) -> array<[same as x]>()

返回所有输入值中 x 的前 n 个最大值。

min(x) -> [same as input]()

返回所有输入值的 最小值。

min(x, n) -> array<[same as x]>()

返回所有输入值中 x 的前 n 个最小值。

reduce_agg(inputValue T, initialState S, inputFunction(S,T,S), combineFunction(S,S,S)) -> S()

将所有输入值减少为单个值。 inputFunction 将为每个输入值调用。除了接受输入值之外,inputFunction 还接受当前状态(最初为 initialState),并返回新状态。 combineFunction 将被调用以将两个状态组合成一个新状态。返回最终状态。如果 initialState 为 NULL,则抛出错误。如果 inputFunctioncombineFunction 返回 NULL,则行为未定义。

在设计 initialStateinputFunctioncombineFunction 时要小心。这些必须支持使用分布式方式评估聚合,使用多个节点上的部分聚合,然后是按组键进行洗牌,最后是最终聚合。考虑状态的所有可能值,以确保 combineFunction交换的结合的 操作,initialState标识 值。

combineFunction(s, initialState) = s for any s

combineFunction(s1, s2) = combineFunction(s2, s1) for any s1 and s2

combineFunction(s1, combineFunction(s2, s3)) = combineFunction(combineFunction(s1, s2), s3) for any s1, s2, s3

此外,确保以下内容适用于 inputFunction

inputFunction(inputFunction(initialState, x), y) = combineFunction(inputFunction(initialState, x), inputFunction(initialState, y)) for any x and y

SELECT id, reduce_agg(value, 0, (a, b) -> a + b, (a, b) -> a + b)
FROM (
    VALUES
        (1, 2),
        (1, 3),
        (1, 4),
        (2, 20),
        (2, 30),
        (2, 40)
) AS t(id, value)
GROUP BY id;
-- (1, 9)
-- (2, 90)

SELECT id, reduce_agg(value, 1, (a, b) -> a * b, (a, b) -> a * b)
FROM (
    VALUES
        (1, 2),
        (1, 3),
        (1, 4),
        (2, 20),
        (2, 30),
        (2, 40)
) AS t(id, value)
GROUP BY id;
-- (1, 24)
-- (2, 24000)

状态类型必须是布尔值、整数、浮点数或日期/时间/间隔。

set_agg(x) -> array<[same as input]>()

返回由不同的输入 x 元素创建的数组。

如果输入包含 NULL,则 NULL 将包含在返回的数组中。如果输入包含包含 NULL 元素的数组或包含 NULL 字段的行,则它们将包含在返回的数组中。此函数使用 IS DISTINCT FROM 来确定不同性。

SELECT set_agg(x) FROM (VALUES(1), (2), (null), (2), (null)) t(x) -- ARRAY[1, 2, null]
SELECT set_agg(x) FROM (VALUES(ROW(ROW(1, null))), ROW((ROW(2, 'a'))), ROW((ROW(1, null))), (null)) t(x) -- ARRAY[ROW(1, null), ROW(2, 'a'), null]
set_union(array(T)) -> array(T)

返回一个数组,其中包含输入中每个数组中包含的所有不同值。

当所有输入均为 NULL 时,此函数返回一个空数组。如果 NULL 是输入数组中的一个元素,则 NULL 将包含在返回的数组中。如果输入包含包含 NULL 元素的数组或包含 NULL 字段的行,则它们将包含在返回的数组中。此函数使用 IS DISTINCT FROM 来确定不同性。

示例

SELECT set_union(elements)
FROM (
    VALUES
        ARRAY[1, 2, 3],
        ARRAY[2, 3, 4]
) AS t(elements);

返回 ARRAY[1, 2, 3, 4]

sum(x) -> [same as input]()

返回所有输入值的总和。

位聚合函数

bitwise_and_agg(x) -> bigint()

返回所有输入值的按位与,以二进制补码表示。

bitwise_or_agg(x) -> bigint()

返回所有输入值的按位或运算结果,以二进制补码表示。

bitwise_xor_agg(x) -> bigint()

返回所有输入值的按位异或运算结果,以二进制补码表示。

映射聚合函数

histogram(x) -> map(K, bigint)

返回一个映射,其中包含每个输入值出现的次数。

map_agg(key, value) -> map(K, V)

返回根据输入的 key / value 对创建的映射。

map_union(x(K, V)) -> map(K, V)

返回所有输入映射的并集。如果在一个以上输入映射中找到一个键,则结果映射中该键的值将来自任意一个输入映射。

map_union_sum(x(K, V)) -> map(K, V)

返回所有输入映射的并集,对所有映射中匹配键的值进行求和。原始映射中的所有空值都被合并为 0。

multimap_agg(key, value) -> map(K, array(V))

返回根据输入的 key / value 对创建的多映射。每个键可以与多个值关联。

近似聚合函数

approx_distinct(x) -> bigint()

返回所有输入值的近似不同值数量。此函数提供对 count(DISTINCT x) 的近似值。如果所有输入值都为空,则返回零。

此函数应产生 2.3% 的标准误差,这是所有可能集合的(近似正态)误差分布的标准差。它不保证对任何特定输入集合的误差上限。

approx_distinct(x, e) -> bigint()

返回所有输入值的近似不同值数量。此函数提供对 count(DISTINCT x) 的近似值。如果所有输入值都为空,则返回零。

此函数应产生不超过 e 的标准误差,这是所有可能集合的(近似正态)误差分布的标准差。它不保证对任何特定输入集合的误差上限。此函数的当前实现要求 e 处于 [0.0040625, 0.26000] 范围内。

approx_percentile(x, percentage) -> [same as x]()

返回所有输入值 x 的近似百分位数,位于给定的 percentage 处。 percentage 的值必须介于零和一之间,并且对于所有输入行必须是常数。

approx_percentile(x, percentage, accuracy) -> [same as x]()

approx_percentile(x, percentage) 相同,但最大秩误差为 accuracyaccuracy 的值必须介于零和一之间(不包括),并且对于所有输入行必须是常数。请注意,较低的“精度”实际上是较低的误差阈值,因此更准确。默认精度为 0.01

approx_percentile(x, percentages) -> array<[same as x]>()

返回所有输入值 x 的近似百分位数,位于指定的百分比数组中的每个百分比处。 percentages 数组中的每个元素必须介于零和一之间,并且该数组对于所有输入行必须是常数。

approx_percentile(x, percentages, accuracy) -> array<[same as x]>()

approx_percentile(x, percentages) 相同,但最大秩误差为 accuracy

approx_percentile(x, w, percentage) -> [same as x]()

使用每个项目的权重 w 在百分比 p 处返回所有输入值 x 的近似加权百分位数。权重必须是至少为一的整数值。它实际上是百分位数集合中值 x 的复制次数。 p 的值必须介于零和一之间,并且对于所有输入行必须是常数。

approx_percentile(x, w, percentage, accuracy) -> [same as x]()

approx_percentile(x, w, percentage) 相同,但最大秩误差为 accuracy

approx_percentile(x, w, percentages) -> array<[same as x]>()

使用每个项目的权重 w 在数组中给定的每个百分比处返回所有输入值 x 的近似加权百分位数。权重必须是至少为一的整数值。它实际上是百分位数集合中值 x 的复制次数。数组中的每个元素必须介于零和一之间,并且该数组对于所有输入行必须是常数。

approx_percentile(x, w, percentages, accuracy) -> array<[same as x]>()

approx_percentile(x, w, percentages) 相同,但最大秩误差为 accuracy

approx_set(x) -> HyperLogLog()

参见 HyperLogLog 函数.

merge(x) -> HyperLogLog()

参见 HyperLogLog 函数.

khyperloglog_agg(x) -> KHyperLogLog()

参见 KHyperLogLog 函数.

merge(qdigest(T)) -> qdigest(T)

参见 分位数摘要函数.

qdigest_agg(x) -> qdigest<[same as x]>()

参见 分位数摘要函数.

qdigest_agg(x, w) -> qdigest<[same as x]>()

参见 分位数摘要函数.

qdigest_agg(x, w, accuracy) -> qdigest<[same as x]>()

参见 分位数摘要函数.

numeric_histogram(buckets, value, weight) -> map<double, double>()

计算一个近似直方图,最多包含 buckets 个桶,用于所有具有每项权重为 weightvalue。返回的映射的键大致是 bin 的中心,而条目是 bin 的总权重。该算法松散地基于 [BenHaimTomTov2010]

buckets 必须为 bigintvalueweight 必须为数字。

numeric_histogram(buckets, value) -> map<double, double>()

计算一个近似直方图,最多包含 buckets 个桶,用于所有 value。此函数等效于 numeric_histogram() 的变体,该变体接受一个 weight,每项权重为 1。在这种情况下,返回映射中的总权重是 bin 中的项目数。

统计聚合函数

corr(y, x) -> double()

返回输入值的关联系数。

covar_pop(y, x) -> double()

返回输入值的总体协方差。

covar_samp(y, x) -> double()

返回输入值的样本协方差。

entropy(c) -> double()

返回计数输入值的以 2 为底的对数熵。

\[\mathrm{entropy}(c) = \sum_i \left[ {c_i \over \sum_j [c_j]} \log_2\left({\sum_j [c_j] \over c_i}\right) \right].\]

c 必须为一个包含非负值的 bigint 列。

该函数忽略任何 NULL 计数。如果非 NULL 计数的总和为 0,则返回 0。

kurtosis(x) -> double()

返回所有输入值的超峰度。使用以下表达式进行无偏估计

\[\mathrm{kurtosis}(x) = {n(n+1) \over (n-1)(n-2)(n-3)} { \sum[(x_i-\mu)^4] \over \sigma^4} -3{ (n-1)^2 \over (n-2)(n-3) }\]

其中 \(\mu\) 是均值,\(\sigma\) 是标准差。

regr_intercept(y, x) -> double()

返回输入值的线性回归截距。 y 是因变量。 x 是自变量。

regr_slope(y, x) -> double()

返回输入值的线性回归斜率。 y 是因变量。 x 是自变量。

regr_avgx(y, x) -> double()

返回一组中自变量的平均值。 y 是因变量。 x 是自变量。

regr_avgy(y, x) -> double()

返回一组中因变量的平均值。 y 是因变量。 x 是自变量。

regr_count(y, x) -> double()

返回非空输入值对的数量。 y 是因变量。 x 是自变量。

regr_r2(y, x) -> double()

返回线性回归的判定系数。 y 是因变量。 x 是自变量。

regr_sxy(y, x) -> double()

返回一组中因变量和自变量的乘积之和。 y 是因变量。 x 是自变量。

regr_syy(y, x) -> double()

返回一组中因变量的平方和。 y 是因变量。 x 是自变量。

regr_sxx(y, x) -> double()

返回一组中自变量的平方和。 y 是因变量。 x 是自变量。

skewness(x) -> double()

返回所有输入值的偏度。

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()

返回所有输入值的样本方差。

分类指标聚合函数

以下每个函数都测量二元 混淆矩阵 的一些指标如何随分类阈值变化而变化。它们旨在与之结合使用。

例如,要找到 精确率-召回率曲线,请使用

WITH
    recall_precision AS (
        SELECT
            CLASSIFICATION_RECALL(10000, correct, pred) AS recalls,
            CLASSIFICATION_PRECISION(10000, correct, pred) AS precisions
        FROM
           classification_dataset
    )
SELECT
    recall,
    precision
FROM
    recall_precision
CROSS JOIN UNNEST(recalls, precisions) AS t(recall, precision)

要获取这些值的对应阈值,请使用

WITH
    recall_precision AS (
        SELECT
            CLASSIFICATION_THRESHOLDS(10000, correct, pred) AS thresholds,
            CLASSIFICATION_RECALL(10000, correct, pred) AS recalls,
            CLASSIFICATION_PRECISION(10000, correct, pred) AS precisions
        FROM
           classification_dataset
    )
SELECT
    threshold,
    recall,
    precision
FROM
    recall_precision
CROSS JOIN UNNEST(thresholds, recalls, precisions) AS t(threshold, recall, precision)

要找到 ROC 曲线,请使用

WITH
    fallout_recall AS (
        SELECT
            CLASSIFICATION_FALLOUT(10000, correct, pred) AS fallouts,
            CLASSIFICATION_RECALL(10000, correct, pred) AS recalls
        FROM
           classification_dataset
    )
SELECT
    fallout
    recall,
FROM
    recall_fallout
CROSS JOIN UNNEST(fallouts, recalls) AS t(fallout, recall)
classification_miss_rate(buckets, y, x, weight) -> array<double>()

计算最多包含 buckets 个桶的错误率。返回一个错误率值的数组。

y 应为布尔结果值; x 应为预测值,每个预测值介于 0 和 1 之间; weight 应为非负值,表示实例的权重。

错误率 定义为一个序列,其第 \(j\) 个条目是

\[{ \sum_{i \;|\; x_i \leq t_j \bigwedge y_i = 1} \left[ w_i \right] \over \sum_{i \;|\; x_i \leq t_j \bigwedge y_i = 1} \left[ w_i \right] + \sum_{i \;|\; x_i > t_j \bigwedge y_i = 1} \left[ w_i \right] },\]

其中 \(t_j\) 是第 \(j\) 个最小的阈值,而 \(y_i\)\(x_i\)\(w_i\) 分别是 yxweight 的第 \(i\) 个元素。

classification_miss_rate(buckets, y, x) -> array<double>()

此函数等效于接受 weightclassification_miss_rate() 变体,每个项目的权重为 1

classification_fall_out(buckets, y, x, weight) -> array<double>()

计算最多包含 buckets 个桶的漏报率。返回一个包含漏报率值的数组。

y 应为布尔结果值; x 应为预测值,每个预测值介于 0 和 1 之间; weight 应为非负值,表示实例的权重。

漏报率 被定义为一个序列,其第 \(j\) 个元素为

\[{ \sum_{i \;|\; x_i > t_j \bigwedge y_i = 0} \left[ w_i \right] \over \sum_{i \;|\; y_i = 0} \left[ w_i \right] },\]

其中 \(t_j\) 是第 \(j\) 个最小的阈值,而 \(y_i\)\(x_i\)\(w_i\) 分别是 yxweight 的第 \(i\) 个元素。

classification_fall_out(buckets, y, x) -> array<double>()

此函数等效于接受 weightclassification_fall_out() 变体,每个项目的权重为 1

classification_precision(buckets, y, x, weight) -> array<double>()

计算最多包含 buckets 个桶的精确率。返回一个包含精确率值的数组。

y 应为布尔结果值; x 应为预测值,每个预测值介于 0 和 1 之间; weight 应为非负值,表示实例的权重。

精确率 被定义为一个序列,其第 \(j\) 个元素为

\[{ \sum_{i \;|\; x_i > t_j \bigwedge y_i = 1} \left[ w_i \right] \over \sum_{i \;|\; x_i > t_j} \left[ w_i \right] },\]

其中 \(t_j\) 是第 \(j\) 个最小的阈值,而 \(y_i\)\(x_i\)\(w_i\) 分别是 yxweight 的第 \(i\) 个元素。

classification_precision(buckets, y, x) -> array<double>()

此函数等效于接受 weightclassification_precision() 变体,每个项目的权重为 1

classification_recall(buckets, y, x, weight) -> array<double>()

计算最多包含 buckets 个桶的召回率。返回一个包含召回率值的数组。

y 应为布尔结果值; x 应为预测值,每个预测值介于 0 和 1 之间; weight 应为非负值,表示实例的权重。

召回率 被定义为一个序列,其第 \(j\) 个元素为

\[{ \sum_{i \;|\; x_i > t_j \bigwedge y_i = 1} \left[ w_i \right] \over \sum_{i \;|\; y_i = 1} \left[ w_i \right] },\]

其中 \(t_j\) 是第 \(j\) 个最小的阈值,而 \(y_i\)\(x_i\)\(w_i\) 分别是 yxweight 的第 \(i\) 个元素。

classification_recall(buckets, y, x) -> array<double>()

此函数等效于接受 weightclassification_recall() 变体,每个项目的权重为 1

classification_thresholds(buckets, y, x) -> array<double>()

计算最多包含 buckets 个桶的阈值。返回一个包含阈值值的数组。

y 应为布尔结果值;x 应为预测值,每个预测值介于 0 和 1 之间。

阈值被定义为一个序列,其第 \(j\) 个元素是第 \(j\) 个最小的阈值。

微分熵函数

以下函数近似二元 微分熵。也就是说,对于一个随机变量 \(x\),它们近似

\[h(x) = - \int x \log_2\left(f(x)\right) dx,\]

其中 \(f(x)\)\(x\) 的偏密度函数。

differential_entropy(sample_size, x)

返回来自随机变量样本结果的近似 log-2 微分熵。该函数在内部创建一个水库(参见 [Black2015]),然后通过近似累积分布的导数(参见 [Alizadeh2010])从样本结果计算熵。

sample_size (long) 是水库样本的最大数量。

x (double) 是样本。

例如,要使用 1000000 个水库样本查找 datax 的微分熵,请使用

SELECT
    differential_entropy(1000000, x)
FROM
    data

注意

如果 \(x\) 有已知的上下限,请首选接受 (bucket_count, x, 1.0, "fixed_histogram_mle", min, max)(bucket_count, x, 1.0, "fixed_histogram_jacknife", min, max) 的版本,因为它们具有更好的收敛性。

differential_entropy(sample_size, x, weight)

返回来自随机变量样本结果的近似 log-2 微分熵。该函数在内部创建一个加权水库(参见 [Efraimidis2006]),然后通过近似累积分布的导数(参见 [Alizadeh2010])从样本结果计算熵。

sample_size 是水库样本的最大数量。

x (double) 是样本。

weight (double) 是一个非负双精度值,指示样本的权重。

例如,要使用 1000000 个水库样本查找具有 data 的权重 weightx 的微分熵,请使用

SELECT
    differential_entropy(1000000, x, weight)
FROM
    data

注意

如果 \(x\) 有已知的上下限,请首选接受 (bucket_count, x, weight, "fixed_histogram_mle", min, max)(bucket_count, x, weight, "fixed_histogram_jacknife", min, max) 的版本,因为它们具有更好的收敛性。

differential_entropy(bucket_count, x, weight, method, min, max) -> double()

返回来自随机变量样本结果的近似 log-2 微分熵。该函数在内部创建一个样本值的观念直方图,计算计数,然后使用最大似然(带或不带 Jacknife 校正)近似熵,具体取决于 method 参数。如果使用 Jacknife 校正(参见 [Beirlant2001]),则估计值为

\[n H(x) - (n - 1) \sum_{i = 1}^n H\left(x_{(i)}\right)\]

其中 \(n\) 是序列的长度,而 \(x_{(i)}\) 是删除了第 \(i\) 个元素的序列。

bucket_count (long) 确定直方图桶的数量。

x (double) 是样本。

method (varchar) 可以是 'fixed_histogram_mle'(用于最大似然估计)或 'fixed_histogram_jacknife'(用于 Jacknife 校正的最大似然估计)。

minmax(均为 double)分别是最小值和最大值;如果输入值超出此范围,函数将抛出异常。

weight (double) 是样本的权重,必须是非负数。

例如,要查找 x 的微分熵,每个值介于 0.01.0 之间,使用 1000000 个箱子和刀切估计值,权重为 data 的 1.0,请使用

SELECT
    differential_entropy(1000000, x, 1.0, 'fixed_histogram_jacknife', 0.0, 1.0)
FROM
    data

要查找 x 的微分熵,每个值介于 -2.02.0 之间,使用 1000000 个桶和最大似然估计值,权重为 dataweight,请使用

SELECT
    differential_entropy(1000000, x, weight, 'fixed_histogram_mle', -2.0, 2.0)
FROM
    data

注意

如果 \(x\) 没有已知的下限和上限,最好使用接受 (sample_size, x)(无权重情况)或 (sample_size, x, weight)(有权重情况)的版本,因为它们使用蓄水池抽样,不需要样本的已知范围。

否则,如果不同权重的数量较少,特别是样本数量较少的情况下,可以考虑使用接受 (bucket_count, x, weight, "fixed_histogram_jacknife", min, max) 的版本,因为刀切偏差校正优于最大似然估计。但是,如果不同权重的数量很多,可以考虑使用接受 (bucket_count, x, weight, "fixed_histogram_mle", min, max) 的版本,因为这将减少内存和运行时间。

approx_most_frequent(buckets, value, capacity) -> map<[same as value], bigint>()

近似计算最多 buckets 个元素的最频繁值。近似估计函数使我们能够用更少的内存选取频繁值。较大的 capacity 提高了底层算法的准确性,但会牺牲内存容量。返回值是一个映射,包含具有相应估计频率的顶级元素。

函数的误差取决于值的排列及其基数。我们可以将容量设置为与底层数据的基数相同,以实现最小的误差。

bucketscapacity 必须是 bigintvalue 可以是数字或字符串类型。

该函数使用 A.Metwally、D.Agrawal 和 A.Abbadi 在论文 Efficient computation of frequent and top-k elements in data streams 中提出的流式摘要数据结构。

蓄水池抽样函数

蓄水池抽样函数使用固定的样本大小,而不是 TABLESAMPLE。固定样本大小始终会导致固定的总大小,同时仍保证数据集中的每个记录都有相同的被选中的概率。参见 [Vitter1985].

reservoir_sample(initial_sample: array(T), initial_processed_count: bigint, values_to_sample: T, desired_sample_size: int) -> row(processed_count: bigint, sample: array(T))

计算给定以下参数的新蓄水池样本:

  • initial_sample:初始样本数组,如果要创建新样本,则为 NULL

  • initial_processed_count:生成初始样本数组时处理的记录数量。如果 initital_sampleNULL,则此值应为 0 或 NULL

  • values_to_sample:要从中抽样的列。

  • desired_sample_size:蓄水池样本的大小。

该函数输出一个具有两列的单行类型:

  1. 已处理计数:函数从中抽取的总行数。它包含提供的 initial_processed_count 中的总数。

  2. 蓄水池样本:一个数组,其长度等效于 desired_sample_sizevalues_to_sample 参数中的值数量的最小值。

WITH result as (
    SELECT
        reservoir_sample(NULL, 0, col, 5) as reservoir
    FROM (
        VALUES
        1, 2, 3, 4, 5, 6, 7, 8, 9, 0
    ) as t(col)
)
SELECT
    reservoir.processed_count, reservoir.sample
FROM result;
 processed_count |     sample
-----------------+-----------------
              10 | [1, 2, 8, 4, 5]

要将旧样本与新数据合并,请向 initial_sample 参数和 initial_processed_count 参数提供有效参数。

WITH initial_sample as (
    SELECT
        reservoir_sample(NULL, 0, col, 3) as reservoir
    FROM (
        VALUES
        0, 1, 2, 3, 4
    ) as t(col)
),
new_sample as (
    SELECT
        reservoir_sample(
            (SELECT reservoir.sample FROM initial_sample),
            (SELECT reservoir.processed_count FROM initial_sample),
            col,
            3
        ) as result
    FROM (
        VALUES
        5, 6, 7, 8, 9
    ) as t(col)
)
SELECT
    result.processed_count, result.sample
FROM new_sample;
 processed_count |  sample
-----------------+-----------
              10 | [8, 3, 2]

要对表的整行进行抽样,请使用 ROW 类型的输入,每个子字段对应源表的列。

WITH result as (
    SELECT
        reservoir_sample(NULL, 0, CAST(row(idx, val) AS row(idx int, val varchar)), 2) as reservoir
    FROM (
        VALUES
        (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')
    ) as t(idx, val)
)
SELECT
    reservoir.processed_count, reservoir.sample
FROM result;
 processed_count |              sample
-----------------+----------------------------------
               5 | [{idx=1, val=a}, {idx=5, val=e}]

噪声聚合函数

参见 噪声聚合函数.


[Alizadeh2010] (1,2)

Alizadeh Noughabi, Hadi & Arghami, N. (2010). “A New Estimator of Entropy”.

[Beirlant2001]

Beirlant, Dudewicz, Gyorfi, and van der Meulen, “Nonparametric entropy estimation: an overview”, (2001)

[BenHaimTomTov2010]

Yael Ben-Haim and Elad Tom-Tov, “A streaming parallel decision tree algorithm”, J. Machine Learning Research 11 (2010), pp. 849–872.

[Black2015]

Black, Paul E. (26 January 2015). “Reservoir sampling”. Dictionary of Algorithms and Data Structures.

[Efraimidis2006]

Efraimidis, Pavlos S.; Spirakis, Paul G. (2006-03-16). “Weighted random sampling with a reservoir”. Information Processing Letters. 97 (5): 181–185.

[Vitter1985]

Vitter, Jeffrey S. “Random sampling with a reservoir.” ACM Transactions on Mathematical Software (TOMS) 11.1 (1985): 37-57.