聚合函数 (Aggregate Functions)
1. 简介
聚合函数的作用是从一组数据(多行)中计算并返回单个值。它们通常与 GROUP BY 子句结合使用,用于生成统计报表,如计算总和、平均值或计数。
SQLite 支持标准 SQL 的聚合函数,并提供了一些特有的增强功能。
2. 示例数据环境
为了演示,假设我们需要分析一张 sales (销售表):
注意:第 4 行的 amount 为 NULL。
3. 标准聚合函数
3.1 COUNT (计数)
计算行数或非 NULL 值的数量。
COUNT(*): 计算所有行,包括 NULL 值。COUNT(column): 计算指定列中非 NULL 的行数。
3.2 SUM (求和)
计算数值列的总和。自动忽略 NULL 值。如果所有值均为 NULL,结果返回 NULL(而不是 0)。
3.3 AVG (平均值)
计算数值列的平均值。
算法逻辑:SUM(column) / COUNT(column)。它只统计非 NULL 的行作为分母。
3.4 MIN / MAX (极值)
查找一组数值中的最小值或最大值。也可用于文本(按字典序)或日期。
4. 字符串聚合:GROUP_CONCAT
这是 SQLite 中非常实用且特有的函数(其他数据库可能有 STRING_AGG)。它将组内非 NULL 的字符串连接成一个长字符串。
语法: group_concat(column, separator)
separator默认为逗号,。
场景: 列出每个分类下包含的所有产品名称。
结果:
注意:输出顺序通常是不确定的,除非在子查询中预先排序。
5. 核心搭档:GROUP BY 和 HAVING
聚合函数的真正威力在于配合分组使用。
5.1 GROUP BY
将结果集按一个或多个列进行分组,聚合函数将分别计算每个组的值。
场景: 计算每个分类的销售总额。
5.2 HAVING
WHERE 子句过滤行(在分组前执行)。
HAVING 子句过滤分组后的结果(在分组后执行)。
场景: 找出销售总额超过 500 的分类。
6. DISTINCT 去重统计
聚合函数可以与 DISTINCT 关键字结合,先去除重复值再进行计算。
场景: 统计有多少个不同的销售金额(即去掉重复的价格)。
7. 进阶特性:FILTER 子句 (SQLite 3.30+)
在 SQLite 3.30.0(2019年发布)及更高版本中,聚合函数支持标准的 SQL FILTER 子句。这允许你在聚合函数内部直接添加条件,而不需要复杂的 CASE WHEN 语句。
场景: 在一条 SQL 中同时统计“电子产品总销量”和“服装总销量”。
旧写法 (CASE WHEN):
新写法 (FILTER):
这种写法更易读,且意图更清晰。
8. 常见陷阱与注意事项
-
NULL 值的传播: 除了
COUNT(*),大多数聚合函数都会忽略 NULL。但要注意,SUM如果遇到全是 NULL 的组,结果是 NULL,如果希望结果是 0,可以使用TOTAL()函数(SQLite 特有),或者COALESCE(SUM(col), 0)。TOTAL(column):总是返回浮点数,且遇到全 NULL 时返回 0.0。
-
SELECT 列表中的非聚合列: SQLite 有一个著名的“怪癖”(Quirk)。在
GROUP BY查询中,如果你 SELECT 了不在GROUP BY列表中的列,且没有对其使用聚合函数,SQLite 会从该组中随机选择一行返回该列的值(通常是第一行,但不保证)。- 建议:在标准 SQL 模式下,SELECT 列表中的列必须要么在 GROUP BY 中,要么包含在聚合函数中。
9. 总结
- 使用
COUNT、SUM、AVG、MIN、MAX进行基础统计。 - 使用
GROUP_CONCAT进行字符串合并。 - 使用
GROUP BY进行分组,使用HAVING过滤分组结果。 - 使用
FILTER子句(SQLite 3.30+)进行更灵活的条件聚合。 - 务必注意
NULL值在聚合计算中的表现。

