第08章 聚合函数
我们上一章讲到了 SQL 单行函数。实际上 SQL 函数还有一类,叫做聚合(或聚集、分组)函数,它是对一组数据进行汇总的函数,输入的是一组数据的集合,输出的是单个值。
1.聚合函数介绍
什么是聚合函数:聚合函数作用于一组数据,并对一组数据返回一个值。
聚合函数类型:AVG()、SUM()、MAX()、MIN()、COUNT()
聚合函数语法
聚合函数不能嵌套调用。比如不能出现类型"AVG(SUM(字段名称))"形式的调用。
1.1 AVG和SUM函数
可以对数值型数据使用AVG 和 SUM 函数。
SELECT AVG(salary),MAX(salary),MIN(salary),SUM(salary)
FROM employees
WHERE job_id like '%REP%';
1.2 MIN和MAX函数
可以对任意数据类型的数据使用 MIN 和 MAX 函数。
SELECT MIN(hire_date),MAX(hire_date)
FROM employees;
1.3 COUNT函数
COUNT(*)返回表中记录总数,适用于任意数据类型。
SELECT COUNT(*)
FROM employees
WHERE department_id=50;
COUNT(expr) 返回expr不为空的记录总数。
SELECT COUNT(commission_pct)
FROM employees
WHERE department_id=50;
注:AVG(列名)、SUM(列名)、MAX(列名)、MIN(列名)、COUNT(列名),聚合的都是列名不为空的记录,会排除列名为null的记录。换而言之,如果某列的数据有null值,AVG(此列),结果并不是null,再平均的过程中会将null值的排除;同理UM(列名)、MAX(列名)、MIN(列名)、COUNT(列名)。
所以可以得出公式:AVG=SUM/COUNT
例如:
SELECTAVG( salary ),SUM( salary )/ COUNT( salary ), AVG(commission_pct),SUM(commission_pct)/COUNT(commission_pct)
FROMemployees
问题:用count(*),count(1),count(列名)谁好呢?
如果使用的是MyISAM引擎是没有区别的。这种引擎内部有一计数器在维护着行数。
如果使用的是InnoDB引擎,则count(*)=count(1)>count(字段)。
问题:能不能使用count(列名)替换count(*)?
不要使用count(列名)来替代count( * ) ,count( * )是SQL92定义的标准统计行数的语法,跟数据库无关,跟NULL和非NULL有关。
说明:count(*)会统计为NULL的行,而count(列名)不会统计此列为NULL值的行。
2.GROUP BY
2.1 基本使用
可以使用GROUP BY子句将表中的数据分成若干组
SELECT column, group_function(column)FROM table[WHERE condition][GROUP BY group_by_expression][ORDER BY column];
明确:WHERE一定放在FROM后面
在SELECT列表中所有未包含在组函数中的列都应该包含在 GROUP BY子句中
SELECT department_id,AVG(salary)
FROM employees
GROUP BY department_id
包含在 GROUP BY 子句中的列不必包含在SELECT 列表中
SELECT AVG(salary)
FROM employees
GROUP BY department_id
2.2 使用多个列分组
SELECT department_id as dept_id,job_id,SUM(salary)
FROM employees
GROUP BY department_id,job_id
2.3 GROUP BY 中使用WITH ROLLUP
使用WITH ROLLUP 关键字之后,在所有查询出的分组记录之后增加一条记录。
例如1:
SELECTdepartment_id,AVG( salary )
FROMemployees
GROUP BYdepartment_id WITH ROLLUP;
例如2:
例如3:多列分组使用WITH ROLLUP会在每个组的结尾增加一条记录
SELECTdepartment_id,job_id,AVG( salary )
FROMemployees
GROUP BYdepartment_id,job_id WITH ROLLUP;