文章目录
- 1.聚合函数
- 2.group by/having
- 3.group by与子查询
1.聚合函数
聚合函数一般用于统计
- 常用如下:
count(field) //记录数
avg(field) //平均值
min(field) //最小值
max(field) //最大值
sum(field) //总和
- count()使用
/* 统计所有非空字段 */
mysql> select count(comm) as 'record number' from EMP;
+---------------+
| record number |
+---------------+
| 4 |
+---------------+
1 row in set (0.00 sec)
/* 统计所有行,即所有字段的数量,若一行都死null,也算是一条记录 */
mysql> select count(*) 'record numbers' from SALGRADE;
+----------------+
| record numbers |
+----------------+
| 5 |
+----------------+
1 row in set (0.00 sec)
/* 统计所有行,但是扫描的是行首,行首是空的,也算是一行 */
mysql> select count(0) as 'record number' from EMP;
+---------------+
| record number |
+---------------+
| 15 |
+---------------+
1 row in set (0.00 sec)
/* 统计所有行,但是扫描的是行首,行首是空的,不算是一行 */
mysql> select count(empno) as 'record number' from EMP;
+---------------+
| record number |
+---------------+
| 15 |
+---------------+
1 row in set (0.00 sec)
- 测试:
- 其他聚合函数
select avg(sal) as 平均薪金 from emp;
select max(sal) as 最高薪金 from emp;
select min(sal) as 最低薪金 from emp;
select sum(sal) as 薪金总和 from emp;
select avg(sal) as 平均薪金,
max(sal) as 最高薪金,
min(sal) as 最低薪金,
sum(sal) as 薪金总和
from emp;
2.group by/having
- 分组之后再统计
- 分组查询通常用于统计,一般和聚合函数配合使用
分组查询格式
select 分组字段或聚合函数
from 表
group by 分组字段 having 条件
order by 字段
/* 统计各个部门的员工数 */
/* 按照deptno进行分组 */
mysql> select deptno ,count(8) from EMP group by deptno;
+--------+----------+
| deptno | count(8) |
+--------+----------+
| 20 | 5 |
| 30 | 6 |
| 10 | 3 |
| 90 | 1 |
+--------+----------+
4 rows in set (0.00 sec)
/* 分组之后的条件用HAVING,不要用where */
mysql> select deptno ,count(*) cv from EMP group by deptno having cv >= 6;
+--------+----+
| deptno | cv |
+--------+----+
| 30 | 6 |
+--------+----+
1 row in set (0.00 sec)
/* 对cn进行降序 */
mysql> select deptno ,count(*) cv from EMP group by deptno having cv >= 5 order by cv desc;
+--------+----+
| deptno | cv |
+--------+----+
| 30 | 6 |
| 20 | 5 |
+--------+----+
2 rows in set (0.00 sec)
3.group by与子查询
- 要求:查询出薪金成本最高的部门的部门号和部门名称
/* 用连接的方式:
将dept表和emp表连接在一起,但是只是取出了dept.deptno, dept.dname这俩字段
*/
/* select dept.deptno, dept.dname from dept首先找出部门号和部门名称
为什么sum(sal)取部门总工资,因为这里对它group by dept.deptno, dept.dname分组了,select的字段只能是分组group by的字段
select dept.deptno, dept.dname, sum(sal)
from dept, emp
where dept.deptno=emp.deptno
group by dept.deptno, dept.dname
*/
/* select sum(sal) from emp group by deptno是每个部门的总薪资,是对部门进行分组,有多条记录的,子查询
mysql> select sum(sal) from EMP group by deptno;
+----------+
| sum(sal) |
+----------+
| 10875.00 |
| 9400.00 |
| 8750.00 |
| 1200.00 |
+----------+
4 rows in set (0.00 sec)
*/
mysql> select A.deptno,A.dname
from DEPT A,EMP B
where A.deptno=B.deptno
group by A.deptno,A.dname
having sum(sal) >=all (select sum(sal) from EMP group by deptno);
+--------+----------+
| deptno | dname |
+--------+----------+
| 20 | RESEARCH |
+--------+----------+
1 row in set (0.00 sec)
/* 用子查询的方式 :
select sum(sal) from emp group by deptno 看出是一个子查询
步骤:
首先对各部门的总sal进行统计
mysql> select sum(sal) from EMP group by deptno;
+----------+
| sum(sal) |
+----------+
| 10875.00 |
| 9400.00 |
| 8750.00 |
| 1200.00 |
+----------+
4 rows in set (0.00 sec)
接着求出所有部门sal最大的薪资
mysql> select max(t.total) from (select sum(sal) total from EMP group by deptno) t;
+--------------+
| max(t.total) |
+--------------+
| 10875.00 |
+--------------+
1 row in set (0.00 sec)
最终得到:
select A.deptno, A.dname
from DEPT A,EMP B
where A.deptno=B.deptno
group by A.deptno, A.dname
having max(sal) >=
(select max(t.total) from (select sum(sal) total from EMP group by deptno) t);
*/
mysql> select A.deptno, A.dname
from DEPT A,EMP B
where A.deptno=B.deptno
group by A.deptno, A.dname
having sum(sal) >=
(select max(t.total) from (select sum(sal) total from EMP group by deptno) t);
+--------+----------+
| deptno | dname |
+--------+----------+
| 20 | RESEARCH |
+--------+----------+
1 row in set (0.01 sec)
- 小结:
/* 统计所有非空字段 */
select count(comm) as 记录数 from emp;
/* 统计所有行,即所有字段的数量,若一行都死null,也算是一条记录 */
select count(*) as 记录数 from emp;
/* 统计所有行,但是扫描的是行首,行首是空的,也算是一行 */
select count(0) as 记录数 from emp;
/* 统计所有行,但是扫描的是行首,行首是空的,不算是一行 */
select count(empno) as 记录数 from emp;
select avg(sal) as 平均薪金,
max(sal) as 最高薪金,
min(sal) as 最低薪金,
sum(sal) as 薪金总和
from emp;
/* 统计各个部门的员工数 */
/* 按照deptno进行分组 */
select deptno, count(*), from emp group by deptno;
/* 分组之后的条件用HAVING,不要用where */
select deptno, count(*) cn from emp group by deptno HAVING cn > 3;
/* 对cn进行降序 */
select deptno, count(*) cn from emp group by deptno HAVING cn > 3 ORDER BY cn desc;
/*列出各部门信息以及部门人数。
书写步骤:
第一步:
select * from DEPT;
第二步:
select *,(select count(*) from EMP where EMP.deptno=DEPT.deptno group by deptno) from DEPT;
*/
/* 对emp表进行分组才能求出部门人数,更好*/
select *, (select count(*) from emp group by deptno HAVING deptno = dept.deptno) total
from dept;
/* ifnull判断查询的字段是否为空,为空则给他一个0 */
select *, ifnull((select count(*) from emp group by deptno HAVING deptno = dept.deptno), 0) total
from dept;
/* 查询出薪金成本最高的部门的部门号和部门名称 */
/* 用连接的方式: 将dept表和emp表连接在一起,但是只是取出了dept.deptno, dept.dname这俩字段*/
/* select dept.deptno, dept.dname
from dept首先找出部门号和部门名称
为什么sum(sal)取部门总工资,因为这里对它group by dept.deptno, dept.dname分组了,select的字段只能是分组group by的字段
select dept.deptno, dept.dname, sum(sal)
from dept, emp
where dept.deptno=emp.deptno
group by dept.deptno, dept.dname
*/
/* select sum(sal) from emp group by deptno是每个部门的总薪资,是对部门进行分组,有多条记录的,子查询 */
select dept.deptno, dept.dname
from dept, emp
where dept.deptno=emp.deptno
group by dept.deptno, dept.dname
HAVING sum(sal) >= all (select sum(sal) from emp group by deptno)
/* 用子查询的方式 :select sum(sal) from emp group by deptno 看出是一个子查询
*/
select dept.deptno, dept.dname
from dept, emp
where dept.deptno=emp.deptno
group by dept.deptno, dept.dname
HAVING sum(sal) >= (
select max(t.total)
from
(select sum(sal) total from emp group by deptno) t
)