mysql查询(分组查询、链接查询、子查询)

mysql查询

1、分组查询

一、分组查询设计的两个字句:

- group by
- having

二、group by

2.1 order by 【表示经过哪一个或者哪些字段进行排序】

group by 【表示经过哪一个或者哪些字段进行分组】mysql

2.2 案例:找出每一个工做岗位的最高薪水【先按照工做岗位分组,使用max函数求每一组的最高薪水】

select 
	 max(sal)
from
  	emp
group by
 	 job;

以上语句,先按照job分组,而后对每一组使用max(sal)求最高薪水web

select 
	 job,max(sal)
from
  	emp
group by
 	 job;

重点:若一条DQL语句中有group by 字句,那么select关键字后面只能跟参与分组的字段和分组函数。sql

2.3 案例:计算每一个部门的平均薪水【按部门编号分组,对每一组求平均薪水】

select deptno,avg(sal) as avgsal from emp group by deptno;

±-------±------------+
| deptno | avgsal |
±-------±------------+
| 20 | 2175.000000 |
| 30 | 1566.666667 |
| 10 | 2916.666667 |
±-------±------------+svg

2.4 案例:计算不一样部门不一样岗位的最高薪水

select deptno,job,max(sal) from emp group by deptno,job;

2.5 案例:找出每一个岗位的最高薪水,除去岗位为 MANAGER 的部分。

select job,max(sal) from emp where job<>'MANAGER' group by job;

三、having

having和where功能相同,都是为了 完成数据的过滤。二者后面都是添加条件。
where在group by 以前完成过滤;
having在group by以后完成过滤。函数

3.1案例:找出每一个工做岗位的平均薪水。要求显示平均薪水大于1500。

select job,avg(sal) from emp where avg(sal)>1500 group by job;
  ERROR 1111 (HY000): Invalid use of group function
  缘由:where关键字后面不能直接使用分组函数,分组函数必须在分组完成后执行
mysql> select job,avg(sal) from emp  group by job having avg(sal)>1500;

±----------±------------+
| job | avg(sal) |
±----------±------------+
| MANAGER | 2758.333333 |
| ANALYST | 3000.000000 |
| PRESIDENT | 5000.000000 |
±----------±------------+
原则:因为两个函数的效率不一样问题,尽可能在where 中过滤,没法过滤的数据,一般先分组以后在过滤,这时候能够选择使用having。spa

四、 一个完整的DQL语句总结:

select…
from …
where…
group by …
having …
order by…设计

第一:以上的关键字顺序不能变,严格遵照
第二:执行顺序:
一、from 从某张表中检索数据
二、where 通过某条件进行过滤
三、group by 而后分组
四、having 分组以后不满意的在过滤
五、select查询出来
六、order by 排序输出code

2、链接查询

一、链接查询根据出现的年代分类:

-sql92
-sql99【主要掌握】xml

二、链接查询根据链接方式分类:

-内链接: 等值链接 \ 非等值链接 \ 自链接
-外链接:左外链接\右外连接
-全链接【使用不多】排序

三、当多张表进行链接查询,若没有任何条件进行限制,会发生什么现象?

案例:查询每个员工所在部门的名称,要求最终显示员工名和对应部门名。
emp 员工表
±-------±-------+
| ename | deptno |
±-------±-------+
| SIMITH | 20 |
| ALLEN | 30 |
| WARD | 30 |
| JONES | 20 |
| MARTIN | 30 |
| BLAKE | 30 |
| CLARK | 10 |
| SCOTT | 20 |
| KING | 10 |
| TURNER | 30 |
| ADAMS | 20 |
| JAMES | 30 |
| FORD | 20 |
| MILLER | 10 |
±-------±-------+

dept部门表
±-------±------------+
| deptno | dname |
±-------±------------+
| 10 | ACCOUNTING |
| 20 | RESEARCHING |
| 30 | SALES |
| 40 | OPERATIONS |
±-------±------------+
主要分析:多张表链接查询,若没有任何条件进行限制,会发生什么现象?
小知识点:在进行夺标联合查询时,尽可能给表起别名。这样可读性高。

select e.ename,d.dname from emp e ,dept d;

±-------±------------+
| ename | dname |
±-------±------------+
| SIMITH | ACCOUNTING |
| SIMITH | RESEARCHING |
| SIMITH | SALES |
| SIMITH | OPERATIONS |
| ALLEN | ACCOUNTING |
| ALLEN | RESEARCHING |
| ALLEN | SALES |
| ALLEN | OPERATIONS |

56 rows in set (0.00 sec)

结论:若两张表进行链接查询的时候,没有任何条件限制,最终查询结果总数老是两张表记录条数乘积,这种现象被称为笛卡尔积现象。为了不笛卡尔积现象的发生,必须在表连接的时候添加限制条件。

四、案例:查询每个员工所在部门的名称,要求最终显示员工名和对应部门名。

sql92语法:内链接中的等值链接

mysql> select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;

sql99语法:内链接中的等值链接
sql99语法的优势:表链接独立出来了,结构清晰,对表链接不满意的话,能够再追加where进行过滤。

select e.ename,d.dname from emp e  join dept d on e.deptno=d.deptno;

±-------±------------+
| ename | dname |
±-------±------------+
| SIMITH | RESEARCHING |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCHING |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCHING |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCHING |
| JAMES | SALES |
| FORD | RESEARCHING |
| MILLER | ACCOUNTING |
±-------±------------+
14 rows in set (0.01 sec)

五、案例:找出每个员工对应的工资等级,要求显示员工名,工资,工资等级等。

sql92语法:内链接中的非等值链接

select e.ename,s.grade from emp e ,salgrade s where e.sal>=s.losal and e.sal<= s.hisal;

sql99语法:内链接中的非等值链接

select e.ename,e.sal, s.grade from emp e inner join salgrade s on e.sal betwee
n s.losal and s.hisal;  //inner能够省略

±-------±--------±------+
| ename | sal | grade |
±-------±--------±------+
| SIMITH | 800.00 | 1 |
| ALLEN | 1600.00 | 3 |
| WARD | 1250.00 | 2 |
| JONES | 2975.00 | 4 |
| MARTIN | 1250.00 | 2 |
| BLAKE | 2850.00 | 4 |
| CLARK | 2450.00 | 4 |
| SCOTT | 3000.00 | 4 |
| KING | 5000.00 | 5 |
| TURNER | 1500.00 | 3 |
| ADAMS | 1100.00 | 1 |
| JAMES | 950.00 | 1 |
| FORD | 3000.00 | 4 |
| MILLER | 1300.00 | 2 |
±-------±--------±------+

六、案例:找出每个员工的上级领导,要求显示员工名以及对应的领导名。

sql92语法:内链接中的自链接

select a.ename empname, b.ename leadername from emp a , emp b where a.mgr=b.empno;

sql99语法:内链接中的自链接

select a.ename empname, b.ename leadername from emp a inner join emp b on a.mgr=b.empno;//inner能够省略

±--------±-----------+
| empname | leadername |
±--------±-----------+
| SIMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
±--------±-----------+

七、案例:找出每一个员工对应的部门名称,要求部门名称所有显示。

内链接:
A表和B表可以彻底匹配的记录查询出来,被称为内链接;
外链接:【只掌握SQL99语法】
A表和B表可以彻底匹配的记录查询出来以外,将其中一张表的记录所有无条件能查询出来,对方表没有匹配的记录,会自动模拟出NULL与之匹配,这种查询被称为外链接。
外链接的查询结果条数>=内链接的查询结果条数
sql99语法:外链接中的右外链接【右链接】

select e.ename,d.dname from emp e right  outer join dept d on e.deptno=d.deptno;//outer能够省略

sql99语法:外链接中的左外链接【左链接】

select e.ename,d.dname from dept d left  outer join emp e on e.deptno=d.deptno;//outer能够省略

任何一个右外链接均可以写成左外链接,任何一个左外链接也一样能够写成右外链接。
±-------±------------+
| ename | dname |
±-------±------------+
| SIMITH | RESEARCHING |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCHING |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCHING |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCHING |
| JAMES | SALES |
| FORD | RESEARCHING |
| MILLER | ACCOUNTING |
| NULL | OPERATIONS |
±-------±------------+
为何inner和outer能够省略,加上去有什么好处?
-能够省略,区份内外链接依靠的不是这些关键字,而是看SQL语句中是否存在left/right。若存在,表示必定是一个外链接,其余都是内链接;
-加上去的好处是加强可读性。

八、案例:找出每个员工对应的领导名,要求显示全部的员工。

select a.ename empname,b.ename leadername from emp a left join emp b on a
.mgr=b.empno;

±--------±-----------+
| empname | leadername |
±--------±-----------+
| SIMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| KING | NULL |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
±--------±-----------+
14 rows in set (0.00 sec)

九、案例:找出每个员工对应的部门名称,以及该员工对应的工资等级。要求显示员工名、部门名、工资等级。

多张表格进行表链接的语法格式:
select xxx from a join b on 条件 join c on 条件;
原理:a和b表进行表链接以后,a表再和c表进行表链接。

select e.ename,d.dname,s.grade from emp e join dept d on e.deptno=d.deptno join salgrade s on e.sal between s.losal and s.hisal;

±-------±------------±------+
| ename | dname | grade |
±-------±------------±------+
| SIMITH | RESEARCHING | 1 |
| ALLEN | SALES | 3 |
| WARD | SALES | 2 |
| JONES | RESEARCHING | 4 |
| MARTIN | SALES | 2 |
| BLAKE | SALES | 4 |
| CLARK | ACCOUNTING | 4 |
| SCOTT | RESEARCHING | 4 |
| KING | ACCOUNTING | 5 |
| TURNER | SALES | 3 |
| ADAMS | RESEARCHING | 1 |
| JAMES | SALES | 1 |
| FORD | RESEARCHING | 4 |
| MILLER | ACCOUNTING | 2 |
±-------±------------±------+

3、子查询

一、什么是子查询?

-select语句嵌套select语句

二、子查询能够出如今哪里?

select...(select), from.....(select),where....(select)

三、where 后面使用select子查询

案例:找出薪水比公司平均薪水高的员工,要求显示员工名和薪水。
select ename ,sal from emp where sal > avg(sal);
以上语句错误,分组函数不能直接使用在where后面。
第一步:找出公司的平均薪资;
select avg(sal) from emp;
第二步:找出薪水大于平均薪水的员工信息

select ename,sal from emp where sal >(select avg(sal) from emp);

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

四、from后面使用子查询【小窍门:将查询结果看成临时表】

案例:找出每个部门的平均薪水,而且要求显示平均薪水的薪水等级
第一步:找出每一个部门的平均薪水
select deptno, avg(sal) as avgsal from emp group by deptno;
±-------±------------+
| deptno | avgsal |
±-------±------------+
| 20 | 2175.000000 |
| 30 | 1566.666667 |
| 10 | 2916.666667 |
±-------±------------+
第二步:将上面的查询结果看成临时表t,t表和salgrade s表进行表链接,条件:t.avgsal between s.losal and s.hisal;

select
t.deptno,t.avgsal,s.grade
from
t
join
salgrade s
on
t.avgsal between s.losal and s.hisal;
将t表换成第一步的执行结果便可。

select   t.avgsal, s.grade  from (select deptno, avg(sal)  as avgsal   from emp group by deptno) t join salgrade s on  t.avgsal between s.losal and s.hisal;

±------------±------+
| avgsal | grade |
±------------±------+
| 2175.000000 | 4 |
| 1566.666667 | 3 |
| 2916.666667 | 4 |
±------------±------+

五、在select后面使用子查询【了解便可】

select e,ename,(select d,dname from dept d where e.deptno=d.deptno) as dname from emp e;

4、union