第13章 聚合函数
一、聚合函数介绍
实际上 SQL 函数还有一类,叫做聚合(或聚集、分组)函数,它是对一组数据进行汇总的函数,输入的是一组数据的集合,输出的是单个值。(可以是一个字段的数据,也可以是通过分组后每一组的数据)。
1.1 常见的聚合函数
函数 | 解释 |
AVG() | 求一组数据的平均值。(不计算null值)(只适用于数值) |
SUM() | 求一组数据的总和。(不计算null值)(只适用于数值) |
MAX() | 求一组数据中的最大值。(不计算null值)(适用于数值、字符串、日期时间等任意数据类型) |
MIN() | 求一组数据的最小值。(不计算null值)(适用于数值、字符串、日期时间等任意数据类型) |
COUNT() | 求一组数据的个数。(不计算null值)(适用于数值、字符串、日期时间等任意数据类型) |
1.2 聚合函数的语法
注:聚合函数不能嵌套调用。比如不能出现类似“AVG(SUM(字段名称))”形式的调用。
1.3 AVG和SUM函数
只适用于对数值型数据使用AVG 和 SUM 函数。
1.4 MIN和MAX函数
可以对任意数据类型的数据使用 MIN 和 MAX 函数。
1.5 COUNT函数
COUNT(*)返回表中记录总数(或指定字段在查询结果中出现的次数),适用于任意数据类型。
COUNT(expr) 返回expr不为空(null值不计算在内)的记录总数。因为不计算空值,所以expr是字段名时得出的记录总数并不是正确的记录总数。
综上,一共有三种计算记录总数的方式。count(字段)、count(*)、count(1)。其中推荐使用count(*)和count(1)两种方式,其中1表示“并不指明哪一个字段”,相当于拿1来表示每一条记录,当然使用2等任意字符都可以。
问题:用count(*),count(1),count(列名)谁好呢?
其实,对于MyISAM引擎的表是没有区别的,这种引擎内部有一计数器在维护着行数,三者效率相同都是O(1),并且结果也相同。 Innodb引擎的表用count(*),count(1)直接读行数,复杂度是O(n),因为innodb真的要去数一遍,但好于具体的count(列名),故效率:count(*) = count(1) > count(列名)。
问题:能不能使用count(列名)替换count(*)?
不要使用 count(列名)来替代 count(*) , count(*) 是 SQL92 定义的标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。 说明:count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。
AVG = SUM / COUNT 永远成立,因为AVG和SUM也不计算空值。