分组函数(最后总结DQL)

单行处理函数
什么是单行处理函数?
输入一行,输出一行

计算每个员工的年薪?
	select ename,(sal+com)*12 as yearsal from emp;
	+--------+----------+
	| ename  | yearsal  |
	+--------+----------+
	| SMITH  |     NULL |
	| ALLEN  | 22800.00 |
	| WARD   | 21000.00 |
	| JONES  |     NULL |
	| MARTIN | 31800.00 |
	| BLAKE  |     NULL |
	| CLARK  |     NULL |
	| SCOTT  |     NULL |
	| KING   |     NULL |
	| TURNER | 18000.00 |
	| ADAMS  |     NULL |
	| JAMES  |     NULL |
	| FORD   |     NULL |
	| MILLER |     NULL |
	+--------+----------+			会发现有空年薪的情况存在,因为有员工补助是为空的

	remember:数据库中 无论是MySQL,Orcale 只要有和NULL进行运算那么结果也为NULL
	
	ifnull() 空处理函数?
		ifnull(可能为NULL的数据,被当作什么看)
	
	重写之前那句:
	select ename,(sal+ifnull(com,0))*12 as yearsal from emp;
	+--------+----------+
	| ename  | yearsal  |			ifnull(comm,0)  如果comm为null ,则将其等效为0
	+--------+----------+
	| SMITH  |  9600.00 |
	| ALLEN  | 22800.00 |
	| WARD   | 21000.00 |
	| JONES  | 35700.00 |
	| MARTIN | 31800.00 |
	| BLAKE  | 34200.00 |
	| CLARK  | 29400.00 |
	| SCOTT  | 36000.00 |
	| KING   | 60000.00 |
	| TURNER | 18000.00 |
	| ADAMS  | 13200.00 |
	| JAMES  | 11400.00 |
	| FORD   | 36000.00 |
	| MILLER | 15600.00 |
	+--------+----------+
		

分组函数一共5个
分组函数还有另一个名字:多行处理函数
多行处理函数的特点:输入多行,最终输出结果为1行
count计数
sum 求和
avg 求平均
max 最大值
min 最小值

remember:所有的分组函数都是对“某一组”数据进行操作的。

找出工资总和?
	select sum(sal) from emp;
找出最高工资?
	select max(sal) from emp;
找出最低工资?
	select min(sal) from emp;
找出平均工资
	select avg(sal) from emp;
找出总人数?
	select count(*) from emp;

分组函数自动忽略NULL

select count(comm) from emp;
+-------------+
| count(comm) |
+-------------+
|           4 |
+-------------+
select sum(comm) from emp;
+-----------+
| sum(comm) |
+-----------+
|   2200.00 |
+-----------+
对比单行处理函数,可以看到多行处理函数里忽略掉了null(重要)

找出工资高于平均工资的员工

select avg(sal) from emp;//平均工资

首先可能会想到这样写,select ename,sal from emp where sal>avg(sal);  //但是会报错
//err:ERROR 1111 (HY000): Invalid use of group function 无效的使用了分组函数
原因:SQL语句当中有一个语法规则,分组函数不可直接使用在where字句中。(讲完group by 可以知晓),	group by是在where执行之后才会执行的,同时分组函数要在分组(group by)之后再执行。

	select	5
	from		1
	where	2
	group by  3
	having	4
	order by	6
	
	解决:找出高于平均工资的员工
	第一步:找出平均工资
	select avg(sal) from emp;
	+-------------+
	| avg(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后面不能跟分组函数
count(*)和count(某个字段)区别
count(*):不是统计某个字段中数据的个数,而是统计总记录条数。(和某个字段无关)
count(某个字段):表示统计comm字段中不为NULL数据总数量

分组函数也能组合起来用:

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 |
+----------+----------+-------------+----------+----------+

16.goup by 和 having
group by:按照某个字段或者某些字段进行分组
having:having是对分组之后的数据进行再次过滤

案例:找出每个工作岗位的最高薪资。
select max(sal) from emp group by job; //这个是先执行group by(即先用job分组),在执行前面的筛查
注意:分组函数一般都会和group by 联合使用,这也是为什么它称为分组函数的原因。
并且任何一个分组函数(count sum avg max min)都是在group by 语句执行结束之后才会执行的。
当一条sql语句没有group by的话,整张表的数据会自成一组

+-----------+----------+
| job       | max(sal) |
+-----------+----------+
| ANALYST   |  3000.00 |
| CLERK     |  1300.00 |
| MANAGER   |  2975.00 |
| PRESIDENT |  5000.00 |
| SALESMAN  |  1600.00 |
+-----------+----------+

当一条语句有group by的时候,select后面只能跟参加分组的字段以及分组函数。跟其他无关字段会报错,在MySQL中即使能够通过但是没有意义

que:每个岗位的平均工资

select job,avg(sal) from emp group by job;
+-----------+-------------+
| job       | avg(sal)    |
+-----------+-------------+
| ANALYST   | 3000.000000 |
| CLERK     | 1037.500000 |
| MANAGER   | 2758.333333 |
| PRESIDENT | 5000.000000 |
| SALESMAN  | 1400.000000 |
+-----------+-------------+

多个字段能不能联合起来一块分组?
案例:找出每个部门不同工作岗位的最高薪资。

 select
  max(sal),job,deptno 
  from emp 
  group by 
  job,deptno;
  	+----------+-----------+--------+
	| max(sal) | job       | deptno |
	+----------+-----------+--------+
	|  3000.00 | ANALYST   |     20 |
	|  1300.00 | CLERK     |     10 |
	|  1100.00 | CLERK     |     20 |
	|   950.00 | CLERK     |     30 |
	|  2450.00 | MANAGER   |     10 |
	|  2975.00 | MANAGER   |     20 |
	|  2850.00 | MANAGER   |     30 |
	|  5000.00 | PRESIDENT |     10 |
	|  1600.00 | SALESMAN  |     30 |
	+----------+-----------+--------+
 

找出每个部门的最高薪资,要求显示薪资大于2900的数据。

第一步:找到每个部门的最高薪资.
mysql> select max(sal),deptno from emp group by deptno;
+----------+--------+
| max(sal) | deptno |
+----------+--------+
|  5000.00 |     10 |
|  3000.00 |     20 |
|  2850.00 |     30 |
+----------+--------+
第二步:找出薪资大于2900(加having过滤)	//这种方式效率低
select max(sal),deptno from emp group by deptno having max(sal)>2900;

这里为了提高效率 建议先用where
select max(sal),deptno from emp where sal >2900 group by deptno;

假设一个用where无法判断的情况
找出每个部门的平均薪资,要求显示薪资大于2900的数据?
第一步找到部门平均工资
select avg(sal),deptno from emp group by deptno;

+-------------+--------+
| avg(sal)    | deptno |
+-------------+--------+
| 2916.666667 |     10 |
| 2175.000000 |     20 |
| 1566.666667 |     30 |
+-------------+--------+
第一步找到部门平均工资这种情况就必须要使用having进行区分

关于查询结果去重?

select distinct job from emp; //distinct 关键字去除重复记录

select ename , distinct job from emp;
以上的sql语句是错误的
remember:distinct 只能出现在所有字段的最前面

select distinct deptno,job from emp;//distinct是所有后面字段联合起来去重

统计岗位数量?
select count(distinct job) from emp;//去除重复的岗位后再进行计数




总结一个完整的DQL语句怎么写?

select		5
..
from			1
..
where		2
..
group by		3
..
having		4
..
order by		6
..
发布了28 篇原创文章 · 获赞 0 · 访问量 440

猜你喜欢

转载自blog.csdn.net/wenshao007/article/details/104325892
今日推荐