什么是聚合函数:聚合函数作用于一组数据,并对一组数据返回一个值。
聚合函数常用类型: AVG()
、SUM()
、MAX()
、MIN()
、COUNT()
聚合函数不能嵌套调用。比如不能出现类似 AVG(SUM(字段名称))
形式的调用。
AVG
和 SUM
函数
可以对数值类型数据使用 AVG
和 SUM
函数。
SELECT AVG(salary), MAX(salary), MIN(salary), SUM(salary)
FROM employees
WHERE job_id LIKE '%REP%';
MIN
和 MAX
函数
可以对任意数据类型的数据使用 MIN
和 MAX
函数。
SELECT MIN(hire_date), MAX(hire_date)
FROM employees;
COUNT
函数
SELECT COUNT(employee_id),COUNT(1),COUNT(2),COUNT(*)
FROM employees;
COUNT(*)
返回表中记录总数,适用于任意数据类型。
SELECT COUNT(*)
FROM employees
WHERE department_id = 90;
COUNT(expr)
返回 expr 不为空的记录总数。
SELECT COUNT(commission_pct)
FROM employees
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 值的行。
需求:查询公司的平均奖金率
# 错误 没有考虑 NULL
SELECT AVG(commission_pct)
FROM employees;
# 正确
SELECT SUM(commission_pct) / COUNT(IFNULL(commission_pct,0))
FROM employees;
SELECT AVG(IFNULL(commission_pct,0))
FROM employees;