什么是聚合函数:聚合函数作用于一组数据,并对一组数据返回一个值。

聚合函数常用类型: AVG()SUM()MAX()MIN()COUNT()

聚合函数不能嵌套调用。比如不能出现类似 AVG(SUM(字段名称)) 形式的调用。

AVGSUM 函数

可以对数值类型数据使用 AVGSUM 函数。

  1. SELECT AVG(salary), MAX(salary), MIN(salary), SUM(salary)
  2. FROM employees
  3. WHERE job_id LIKE '%REP%';

AVG = SUM / COUNT

MINMAX 函数

可以对任意数据类型的数据使用 MINMAX 函数。

  1. SELECT MIN(hire_date), MAX(hire_date)
  2. FROM employees;

COUNT 函数

  1. SELECT COUNT(employee_id),COUNT(1),COUNT(2),COUNT(*)
  2. FROM employees;

COUNT(*) 返回表中记录总数,适用于任意数据类型

  1. SELECT COUNT(*)
  2. FROM employees
  3. WHERE department_id = 90;

COUNT(expr) 返回 expr 不为空的记录总数。

  1. SELECT COUNT(commission_pct)
  2. FROM employees
  3. WHERE department_id = 90;

问题:用 count(*)count(1)count(列名) 谁好呢?

  • 对于 MyISAM 引擎的表是没有区别的。这种引擎内部有一计数器在维护着行数。
  • InnoDB 引擎的表用 count(*)count(1) 直接读行数,复杂度是 O(n),因为 InnoDB 真的要去数一遍。但好于具体的 count(列名)


    问题:能不能使用 count(列名) 替换 count(*)?
    不要使用 count(列名) 来替代 count(*)count(*) 是 SQL 92 定义的标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。
    说明:count(*) 会统计值为 NULL 的行,而 count(列名) 不会统计此列为 NULL 值的行。

需求:查询公司的平均奖金率

  1. # 错误 没有考虑 NULL
  2. SELECT AVG(commission_pct)
  3. FROM employees;
  4. # 正确
  5. SELECT SUM(commission_pct) / COUNT(IFNULL(commission_pct,0))
  6. FROM employees;
  7. SELECT AVG(IFNULL(commission_pct,0))
  8. FROM employees;