分组查询主要涉及到两个子句,分别是:group by和having。
group by : 按照某个字段或者某些字段进行分组。
having : having是对分组之后的数据进行再次过滤。
group by
取得每个工作岗位的工资合计,要求显示岗位名称和工资合计。
select job,sum(sal) from emp group by job;
+-----------+----------+
| job | sum(sal) |
+-----------+----------+
| CLERK | 4150.00 |
| SALESMAN | 5600.00 |
| MANAGER | 8275.00 |
| ANALYST | 6000.00 |
| PRESIDENT | 5000.00 |
+-----------+----------+
找出每个工作岗位的最高薪资。
select job,max(sal) from emp group by job;
| job | max(sal) |
+-----------+----------+
| CLERK | 1300.00 |
| SALESMAN | 1600.00 |
| MANAGER | 2975.00 |
| ANALYST | 3000.00 |
| PRESIDENT | 5000.00 |
+-----------+----------+
如果使用了order by,order by必须放到group by后面
select job,max(sal) from emp group by job order by job desc;
+-----------+----------+
| job | max(sal) |
+-----------+----------+
| SALESMAN | 1600.00 |
| PRESIDENT | 5000.00 |
| MANAGER | 2975.00 |
| CLERK | 1300.00 |
| ANALYST | 3000.00 |
+-----------+----------+
在SQL语句中若有group by 语句,那么在select语句后面只能跟分组函数+参与分组的字段。
select job,drptno,sum(sal) from emp group by job,deptno;
+-----------+--------+----------+
| job | deptno | sum(sal) |
+-----------+--------+----------+
| ANALYST | 20 | 6000.00 |
| CLERK | 10 | 1300.00 |
| CLERK | 20 | 1900.00 |
| CLERK | 30 | 950.00 |
| MANAGER | 10 | 2450.00 |
| MANAGER | 20 | 2975.00 |
| MANAGER | 30 | 2850.00 |
| PRESIDENT | 10 | 5000.00 |
| SALESMAN | 30 | 5600.00 |
+-----------+--------+----------+
分组函数一般都会和group by联合使用,这也是为什么它被称为分组函数的原因。
并且任何一个分组函数(count sum avg max min)都是在group by语句执行结束之后才会执行的。
当一条sql语句没有group by的话,整张表的数据会自成一组。
having
不使用分组函数
如果想对分组数据再进行过滤需要使用having子句。
select max(sal),deptno from emp group by deptno having max(sal) > 2900;
// 这种方式效率低。
+----------+--------+
| max(sal) | deptno |
+----------+--------+
| 3000.00 | 20 |
| 5000.00 | 10 |
+----------+--------+
select max(sal),deptno from emp where sal > 2900 group by deptno;
// 效率较高,建议能够使用where过滤的尽量使用where。
| max(sal) | deptno |
+----------+--------+
| 3000.00 | 20 |
| 5000.00 | 10 |
+----------+--------+
以上两种写法得到的结果是一样的,所以在不使用聚合函数时,having可以看作是where的另一种表达。
使用分组函数
select deptno,avg(sal) from emp group by deptno having avg(sal) > 2000;
+--------+-------------+
| deptno | avg(sal) |
+--------+-------------+
| 20 | 2175.000000 |
| 10 | 2916.666667 |
+--------+-------------+
分组函数的执行顺序:
根据条件查询数据
分组
采用having过滤,取得正确的数据
select deptno,avg(sal) from emp where avg(sal) > 2000 group by deptno;
// 错误了。
因为需要筛选的内容是带分组函数的,所以不能使用where,只能用having进行筛选。
select语句总结
select 字段
from 表名
where …….
group by ………
having …….(就是为了过滤分组后的数据而存在的—不可以单独的出现)
order by ………
以上语句的执行顺序
1.首先执行where语句过滤原始数据
2.执行group by进行分组
3.执行having对分组数据进行操作
4.执行select选出数据
5.执行order by排序
原则:能在where中过滤的数据,尽量在where中过滤,效率较高。having的过滤是专门对分组之后的数据进行过滤的。