第一部分:/p/63217422
第二部分:/p/64153448
Day3
九.连接查询
1.什么是连接查询?
2.连接查询根据:年代分类
---SQL92【1992】
---SQL99【1999:更新的语法,主要掌握这种语法】
总结:
92语法和99语法的区别,
92语法中的from后面多表相互连接是用逗号,后用查询条件是用where。
而99语法中的from后面多表相互连接的是用join,后面查询条件前用 on。
3.连接查询根据:连接方式分类
---内连接:
*等值连接
*非等值连接
*自连接
---外连接
*左外连接(左连接)
*右外连接(右连接)
---全连接【很少使用】
内连接含义:
只连接匹配的行,即A表与B表相连接,能够匹配的记录查询出来。
外连接含义:
A表和B表能够完全匹配的记录查询出来之外,将其中一张表的记录无条件的完全查询出来,对方表没有匹配的记录时,会自动模拟出null值与之匹配;外连接的查询结果条数 >= 内连接的查询结果条数。
❗小知识点:在进行多表连接查询的时候,尽量给表起别名,这样mysql容易识别某个字段具体取自于哪张表。
> select e.ename,d.dname from emp e,dept d;
问:当多张表进行连接查询,若没有任何条件进行限制,会发生什么现象?
结论:若两张表进行连接查询的时候没有任何条件限制,最终的查询结果总数是两张表记录的乘积,该现在称为笛卡尔积现象。所以在使用表连接时,添加限制条件。
以下为三张表具体信息内容:
内连接中的等值连接
案例1:查询每一个员工所在的部门名称,要求最终显示员工姓名和对应的部门名称。(两张表查询)
SQL92语法:
eg:select e.ename,d.dname from emp e,dept d where e.xx=d.xx
>select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;
SQL99语法:
>select e.ename,d.dname from emp e inner join dept d on e.deptno=d.deptno; //inner 可以省略
>select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno;(重点掌握)
内连接中的非等值连接
案例2:找出每一个员工对应的工资等级,要求显示员工姓名、工资、工资等级。(两张表查询)
SQL92语法:
> select e.ename,e.sal,s.grade from emp e , salgrade s where e.sal between s.losal and s.hisal;
SQL99语法:
> select e.ename,e.sal,s.grade from emp e inner join salgrade s on e.sal between s.losal and s.hisal; //inner 可以省略
> select e.ename,e.sal,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;(重点掌握)
内连接中的自连接
案例3:找出每一个员工的上级领导,要求显示员工姓名及对应的领导姓名。(一张表查询)
92语法和99语法,主要是将join改为逗号,on 改为 where
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 可以省略
> select a.ename empname,b.ename leadername from emp a join emp b on a.mgr=b.empno;(重点掌握)
外连接
案例4:找出每一个员工对应的部门名称,要求部门名称全部显示。(给表起别名,a为员工表,b为领导表,两张表查询)
可以发现员工信息表中的部门编号只有10-30,没有出现40,即要求把部门名称全部显示的话,员工表需要对应空值。
#右外连接
> select a.ename,a.deptno,b.dname from emp a right outer join dept b on a.deptno=b.deptno;//outer可以省略
#左外连接
> select a.ename,a.deptno,b.dname from dept b left outer join emp a on a.deptno=b.deptno;
Ps:为什么 inner 和 outer 可以省略,加上去有什么好处?
可以省略,因为区分内连接与外连接不是依靠这两个关键字,而是看SQL语句中的left/right关键字;
加上left、right关键字增强SQL语句的可读性。
案例5:找出每一个员工对应的领导名,要求显示所有员工。
> select a.ename empname,b.ename leadername from emp a left outer join emp b ona.mgr=b.empno;//outer可省略
案例6:找出每一个员工对应的部门名称,以及该员工对应的工资等级,要求显示员工姓名、部门名、工资,工资等级。(三张表查询,以下自设表别名,a为员工表,b为部门表,c为工资等级表)
> > select a.ename,b.dname,a.sal,c.grade from emp a join dept b on a.deptno=b.deptno join salgrade c on a.sal between c.losal and c.hisal;
注意:使用多张表查询时,from后面可跟多个join ,join前面的表跟后面的表分别建立连接。
多张表进行表连接的语法格式:
原理:A表和B表通过连接条件1连接之后,A表再和C表通过连接条件2进行连接;
-----------------------------------------------------------------------------------------------
十,子查询
含义:select 语句嵌套 select 语句。
select子句可出现在select、from、where关键字后面,如下:
select … (select)…
from …(select)…
where …(select)…
10.1子查询--出现在where后面
案例1:找出薪水比公司平均薪水高的员工,要求显示员工名和薪水
having也可以用where。这里需要注意的是,where后面不能直接跟分组函数,所以需要分开写;下面另一种方法,可以用一行代码即可查询出来---where后面的子查询。
> select ename,sal from emp where sal>(select avg(sal) from emp);
10.2子查询--出现在from后面
案例2:找出每个部门的平均薪水,并且要求显示平均薪水的薪水等级
解决思路:
第一步,找出每个部门的平均薪水。
>select deptno,avg(sal) as avgsal from emp group by deptno;
第二步,将上面的查询结果当做临时表t,t表和salgrade s 表进行表连接,条件:t.avg(sal) between s.losal and s.hisal (t.avg(sal)要重命名,因为avg本意为分组函数)
>select t.deptno,t.avgsal,s.grade from salgrade s join t on t.avgsal between s.losal and s.hisal;
--------
以上如果直接粘贴到mysql,会显示t表不存在,所以,将第一步的看成一个整体,粘贴到 from后面的t表前面。
正确代码:
select
t.deptno,t.avgsal,s.grade
from
salgrade s
join
(select deptno,avg(sal) as avgsal from emp group by deptno) t
on
t.avgsal between s.losal and s.hisal;
----
> select t.deptno, t.avgsal, s.grade from ( select avg(sal) as avgsal,deptno from emp group by deptno) t join salgrade s on t.avgsal between s.losal and s.hisal;
PS:主要是根据现有的数据信息,利用子查询转换成想要的数据信息。
小总结:
本篇文章主要介绍了mysql最重要部分,select部分的连接查询和子查询。
本小节已结束,未完待续,敬请期待~~