GROUP BY : 分组查询命令 1.书写顺序: SELECT 字段名,函数,子查询 FROM 表名 WHERE 定位数据行条件 GROUP BY 分组字段 2.执行顺序: FROM-->WHERE-->GROUP BY-->SELECT *****如果同时出现WHERE与GROUP BY;GROUP BY应该在where之后执行***** 3.执行原理: GROUP BY 执行时首先根据分组字段数据种类,对临时表数据行进行分类。然后将具有相同特征的数据行读取出来保存到一个全新临时表 4.七个查询命令中,只有GROUP BY有机会在执行完毕后,一次生成多个临时表。 【重要结论:在一条select语句中,如果有group by语句的话, select后面只能跟:参加分组的字段以及分组函数,其它的一律不能写。】 原因:select与group by联合使用时,只会读取当前临时表下指定字段下的【第一个数据】,此时 select所抓取数据应该是当前临时表所有数据行【公有的特征】,所以此时select抓取的字 段,就应该是group by进行分组的字段。 |
| | | | 硬盘上EMP.frm | | | | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO | 7369 | SMITH | CLERK | 7902 | 1980/12/17 | 800 | NULL | 20 | 7499 | ALLEN | SALESMAN | 7698 | 1981/2/20 | 1600 | 300 | 30 | 7521 | WARD | SALESMAN | 7698 | 1981/2/22 | 1250 | 500 | 30 | 7566 | JONES | MANAGER | 7839 | 1981/4/2 | 2975 | NULL | 20 | 7654 | MARTIN | SALESMAN | 7698 | 1981/9/28 | 1250 | 1400 | 30 | 7698 | BLAKE | MANAGER | 7839 | 1981/5/1 | 2850 | NULL | 30 | 7782 | CLARK | MANAGER | 7839 | 1981/6/9 | 2450 | NULL | 10 | 7788 | SCOTT | ANALYST | 7566 | 1987/4/19 | 3000 | NULL | 20 | 7839 | KING | PRESIDENT | | 1981/11/17 | 5000 | NULL | 10 | 7844 | TURNER | SALESMAN | 7698 | 1981/9/8 | 1500 | 0 | 30 | 7876 | ADAMS | CLERK | 7788 | 1987/5/23 | 1100 | NULL | 20 | 7900 | JAMES | CLERK | 7698 | 1981/12/3 | 950 | NULL | 30 | 7902 | FORD | ANALYST | 7566 | 1981/12/3 | 3000 | NULL | 20 | 7934 | MILLER | CLERK | 7782 | 1982/1/23 | 1300 | NULL | 10 |
|
需求:查询部门30下所有职位的人数 SQL: SELECT JOB,COUNT(*) FROM EMP WHERE DEPTNO = 30 GROUP BY JOB |
第一步:执行 FROM EMP 该命令的执行会在内存中生成一个与源表一样的临时表(第一个临时表) |
| | | | 第一个临时表 | | | | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO | 7369 | SMITH | CLERK | 7902 | 1980/12/17 | 800 | NULL | 20 | 7499 | ALLEN | SALESMAN | 7698 | 1981/2/20 | 1600 | 300 | 30 | 7521 | WARD | SALESMAN | 7698 | 1981/2/22 | 1250 | 500 | 30 | 7566 | JONES | MANAGER | 7839 | 1981/4/2 | 2975 | NULL | 20 | 7654 | MARTIN | SALESMAN | 7698 | 1981/9/28 | 1250 | 1400 | 30 | 7698 | BLAKE | MANAGER | 7839 | 1981/5/1 | 2850 | NULL | 30 | 7782 | CLARK | MANAGER | 7839 | 1981/6/9 | 2450 | NULL | 10 | 7788 | SCOTT | ANALYST | 7566 | 1987/4/19 | 3000 | NULL | 20 | 7839 | KING | PRESIDENT | | 1981/11/17 | 5000 | NULL | 10 | 7844 | TURNER | SALESMAN | 7698 | 1981/9/8 | 1500 | 0 | 30 | 7876 | ADAMS | CLERK | 7788 | 1987/5/23 | 1100 | NULL | 20 | 7900 | JAMES | CLERK | 7698 | 1981/12/3 | 950 | NULL | 30 | 7902 | FORD | ANALYST | 7566 | 1981/12/3 | 3000 | NULL | 20 | 7934 | MILLER | CLERK | 7782 | 1982/1/23 | 1300 | NULL | 10 |
|
第二步:执行 WHERE DEPTNO = 30 1.对第一个临时表进行遍历;循环遍历时,对DEPTNO = 30 (也就是部门编号=30)的数据行进行定位。 2.循环遍历结束后,将满足定位条件的数据行读取出来,生成一个全新的临时表(第二个临时表),第二个临时表生成后,第一个临时表被销毁。 |
| | | | 第二个临时表 | | | | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO | 7499 | ALLEN | SALESMAN | 7698 | 1981/2/20 | 1600 | 300 | 30 | 7521 | WARD | SALESMAN | 7698 | 1981/2/22 | 1250 | 500 | 30 | 7654 | MARTIN | SALESMAN | 7698 | 1981/9/28 | 1250 | 1400 | 30 | 7698 | BLAKE | MANAGER | 7839 | 1981/5/1 | 2850 | NULL | 30 | 7844 | TURNER | SALESMAN | 7698 | 1981/9/8 | 1500 | 0 | 30 | 7900 | JAMES | CLERK | 7698 | 1981/12/3 | 950 | NULL | 30 |
|
第三步:执行 GROUP BY JOB 1. 对第二个临时表JOB字段下数据种类进行统计(统计出多少种,就会生成多少个临时表)。 2. 将具有相同特征的数据行保存到同一个临时表。这些临时表全部生成后,前面由WHERE命令生成的临时表(这里是第二个临时表)就会被销毁。 |
| | | | 第三个临时表 | | | | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO | 7499 | ALLEN | SALESMAN | 7698 | 1981/2/20 | 1600 | 300 | 30 | 7521 | WARD | SALESMAN | 7698 | 1981/2/22 | 1250 | 500 | 30 | 7654 | MARTIN | SALESMAN | 7698 | 1981/9/28 | 1250 | 1400 | 30 | 7844 | TURNER | SALESMAN | 7698 | 1981/9/8 | 1500 | 0 | 30 |
|
| | | | 第四个临时表 | | | | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO | 7698 | BLAKE | MANAGER | 7839 | 1981/5/1 | 2850 | NULL | 30 |
|
| | | | 第五个临时表 | | | | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO | 7900 | JAMES | CLERK | 7698 | 1981/12/3 | 950 | NULL | 30 |
|
第四步:执行 SELECT JOB,COUNT(*) SELECT 执行原理: 1.SELECT执行特点与提供临时表的命令有关。 2.如果临时表由【FROM】或则【WHERE】提供,此时SELECT面对只有一个临时表。此时SELECT将 指定字段下所有内容读取出来生成一个全新的临时表。 3.如果临时表由【group by】提供,此时SELECT可能面对多个临时表。 1)SELECT将依次操作每一个临时表 2)SELECT在操作某个临时表时,只会读取【指定字段下第一个数据】 3)SELECT将从多个临时表读取数据合成一列保存到一个全新的临时表中 根据SELECT命令的执行原理,这里执行SELECT JOB,COUNT(*)命令时将会对刚刚生成的三个临时表(也就是第三个、第四个、第五个临时表)进行操作。然后生成一个全新的临时表(也就是第六个临时表)。 |
| 第六个临时表 | JOB | count(*) | SALESMAN | 4 | MANAGER | 1 | CLERK | 1 |
|
当第六个临时表生成后,由前一个命令生成的第三个、第四个和第五个临时表会被销毁。此时MySQL服务器就会把第六个临时表作为最终的结果推送给客户端,供操作者查阅。 |