分组函数/聚合函数/多行处理函数

  • count
  • sum
  • avg
  • max
  • min
  • 组合聚合函数
  • 单行处理函数



分组函数又名聚合函数、多行处理函数。特点是输入多行,最终输出的结果是1行。

表达式

含义

count

取得记录数

sum

求和

avg

取平均

max

取最大的数

min

取最小的数

分组函数自动忽略空值,不需要手动的加where条件排除空值
符合条件的所有记录总数:
select count(*) from emp where xxx;
comm这个字段中不为空的元素总数:
select count(comm) from emp;
计算comm的总和:
select sum(comm) from emp;select sum(comm) from emp where comm is not null;// 不需要额外添加这个过滤条件。sum函数自动忽略NULL。

注意:分组函数不能直接使用在where关键字后面。具体原因将在分组查询笔记中详解。
select ename,sal from emp where sal > avg(sal);

ERROR 1111 (HY000): Invalid use of group function

那如何找出工资高于平均工资的员工?
第一步:找出平均工资
select avg(sal) from emp;

+-------------+
| avg(sal)    |
+-------------+
| 2073.214286 |
+-------------+

第二步:找出高于平均工资的员工
select ename,sal from emp where sal > 2073.214286;

+-------+---------+
| ename | sal     |
+-------+---------+
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| SCOTT | 3000.00 |
| KING  | 5000.00 |
| FORD  | 3000.00 |
+-------+---------+

简便方法:
select ename,sal from emp where sal > (select avg(sal) from emp);//在where子句中使用需要重新调用select和from。

+-------+---------+
| ename | sal     |
+-------+---------+
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| SCOTT | 3000.00 |
| KING  | 5000.00 |
| FORD  | 3000.00 |
+-------+---------+

count

取得所有员工数:
select count(*) from emp;

+----------+
| count(*) |
+----------+
|       14 |
+----------+

取得comm个数:
select count(comm) from emp;

+-------------+
| count(comm) |
+-------------+
|           4 |
+-------------+

Q:count(*)和count(具体的某个字段),他们有什么区别?
count(*):不是统计某个字段中数据的个数,而是统计总记录条数。(和某个字段无关)
count(comm): 表示统计comm字段中不为NULL的数据总数量。

取得工作岗位的个数:
select count(distinct job ) from emp;//distinct 表示不重复

+----------------------+
| count(distinct job ) |
+----------------------+
|                    5 |
+----------------------+

sum

Sum可以取得某一个列的和,null会被忽略
取得薪水的合计:
select sum(sal) from emp;

+----------+
| sum(sal) |
+----------+
| 29025.00 |
+----------+

获得薪水总和:
select sum(sal+comm) from emp;

+---------------+
| sum(sal+comm) |
+---------------+
|       7800.00 |
+---------------+

从以上结果来看,不正确,原因在于comm字段有null值,所以无法计算,sum会忽略掉,正确的做法是将comm字段转换成0。此处可参考后文单行处理函数ifnull的具体用法:
select sum(sal+IFNULL(comm, 0)) from emp;

+--------------------------+
| sum(sal+IFNULL(comm, 0)) |
+--------------------------+
|                 31225.00 |
+--------------------------+

avg

取得某一列的平均值
取得薪水的平均值:
select avg(sal) from emp;

+-------------+
| avg(sal)    |
+-------------+
| 2073.214286 |
+-------------+

max

取得某个一列的最大值
取得最高薪水:
select max(sal) from emp;

+----------+
| max(sal) |
+----------+
|  5000.00 |
+----------+

取得最晚入职得员工:
select max(str_to_date (hiredate, '%Y-%m-%d')) from emp;

+-----------------------------------------+
| max(str_to_date (hiredate, '%Y-%m-%d')) |
+-----------------------------------------+
| 1987-05-23                              |
+-----------------------------------------+

min

取得某个一列的最小值
取得最低薪水:
select min(sal) from emp;

+----------+
| min(sal) |
+----------+
|   800.00 |
+----------+

取得最早入职得员工:

+----------------------------------------+
| min(str_to_date(hiredate, '%Y-%m-%d')) |
+----------------------------------------+
| 1980-12-17                             |
+----------------------------------------+

组合聚合函数

可以将这些聚合函数都放到select中一起使用:
select count(*),sum(sal),avg(sal),max(sal),min(sal) from emp;

+----------+----------+-------------+----------+----------+
| count(*) | sum(sal) | avg(sal)    | max(sal) | min(sal) |
+----------+----------+-------------+----------+----------+
|       14 | 29025.00 | 2073.214286 |  5000.00 |   800.00 |
+----------+----------+-------------+----------+----------+

单行处理函数

单行处理函数:输入一行,输出一行。(从结果上看是输入多行输出多行)。
上文提到计算每个员工的年薪:
select ename,(sal+comm)*12 as yearsal from emp; 重点:所有数据库都是这样规定的,只要有NULL参与的运算结果一定是NULL。
解决方案:使用ifnull函数:
select ename,(sal+ifnull(comm,0))*12 as yearsal from emp; ifnull(可能为NULL的数据,被当做什么处理) : 属于单行处理函数。
select ename,ifnull(comm,0) as comm from emp;

+--------+---------+
| ename  | comm    |
+--------+---------+
| SMITH  |    0.00 |
| ALLEN  |  300.00 |
| WARD   |  500.00 |
| JONES  |    0.00 |
| MARTIN | 1400.00 |
| BLAKE  |    0.00 |
| CLARK  |    0.00 |
| SCOTT  |    0.00 |
| KING   |    0.00 |
| TURNER |    0.00 |
| ADAMS  |    0.00 |
| JAMES  |    0.00 |
| FORD   |    0.00 |
| MILLER |    0.00 |
+--------+---------+