Skip to content

SQL 聚合函数 详解

SQL 聚合函数、GROUP BY、HAVING 以及 distinct/高级聚合,对应返回值和 orders 表上的一行示例。

聚合函数把多行折叠为一个标量结果。GROUP BY 在聚合前按键划分行。HAVING 在聚合后过滤分组。除 COUNT(*) 外,所有聚合都会跳过 NULL 输入。

参考表格 · 29 条目
29 of 29 rows
标量
非 NULL 输入值的个数;COUNT(*) 统计所有行。SELECT COUNT(*) FROM orders
非 NULL 数值之和。空集时返回 NULL。SELECT SUM(total) FROM orders
非 NULL 数值的算术平均值。忽略 NULL 输入。SELECT AVG(total) FROM orders
任意可比较类型中最小的非 NULL 值。SELECT MIN(total) FROM orders
任意可比较类型中最大的非 NULL 值。SELECT MAX(total) FROM orders
分组
按键划分输入行;聚合按分区分别执行。SELECT user_id, SUM(total) FROM orders GROUP BY user_id
聚合后按组求值的谓词。在聚合场景替代 WHERE。SELECT user_id, COUNT(*) FROM orders GROUP BY user_id HAVING COUNT(*) > 5
一次扫描中为每组计算多个聚合。SELECT user_id, COUNT(*), SUM(total), AVG(total) FROM orders GROUP BY user_id
在一条语句中计算多种分组;当前集合之外的键返回 NULL。SELECT user_id, region, SUM(total) FROM orders GROUP BY GROUPING SETS ((user_id), (region), ())
按层级 grouping sets 的简写;添加小计和总计。SELECT region, user_id, SUM(total) FROM orders GROUP BY ROLLUP (region, user_id)
把所列键的全部组合作为 grouping sets 的简写。SELECT region, user_id, SUM(total) FROM orders GROUP BY CUBE (region, user_id)
在同一个子句中混合普通分组键与 grouping sets。SELECT user_id, region, SUM(total) FROM orders GROUP BY user_id, GROUPING SETS ((region), ())
保留每个键在排序中的第一行。Postgres 扩展。SELECT DISTINCT ON (user_id) user_id, total FROM orders ORDER BY user_id, created_at DESC
去重与进阶
唯一非 NULL 值的个数。先去重再计数。SELECT COUNT(DISTINCT user_id) FROM orders
以有界误差估计不同值的个数;为大规模输入而生。SELECT APPROX_COUNT_DISTINCT(user_id) FROM orders
用分隔符拼接非 NULL 字符串。SELECT STRING_AGG(user_id::text, ',') FROM orders
拼接非 NULL 字符串;即 MySQL 中 STRING_AGG 的名字。SELECT GROUP_CONCAT(user_id SEPARATOR ',') FROM orders
把非 NULL 输入值收集为数组。SELECT ARRAY_AGG(total) FROM orders
把输入行收集为 JSON 数组;JSONB 形式存储解析后的二进制。SELECT JSONB_AGG(user_id) FROM orders
每个 / 任一非 NULL 输入值为 true 时返回 TRUE。SELECT BOOL_AND(total > 0), BOOL_OR(total > 100) FROM orders
BOOL_AND 的标准别名。SELECT EVERY(total > 0) FROM orders
在排序输入上做插值 / 最近秩百分位;需要 WITHIN GROUP。SELECT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY total) FROM orders
出现最多的输入值;Postgres 中的有序集聚合。SELECT MODE() WITHIN GROUP (ORDER BY total) FROM orders
把排序顺序传给有序集和假设集聚合。SELECT RANK(500) WITHIN GROUP (ORDER BY total) FROM orders
把聚合限定在满足条件的行上。SELECT COUNT(*) FILTER (WHERE total > 100) FROM orders
在聚合拼接或收集之前对值排序。SELECT STRING_AGG(user_id::text, ',' ORDER BY user_id) FROM orders
COUNT(*) 和 COUNT(1) 统计每一行;COUNT(col) 跳过 NULL 输入。SELECT COUNT(*), COUNT(total), COUNT(1) FROM orders
非 NULL 数值的样本标准差。STDDEV_POP 给出总体形式;裸名的默认值因引擎而异。SELECT STDDEV(total) FROM orders
非 NULL 数值的样本方差(STDDEV 的平方)。VAR_SAMP 和 VAR_POP 分别命名两种形式。SELECT VARIANCE(total) FROM orders