从一张表中单独查询,称为单表查询。
跨表、多表联合起来查询称为连接查询。
分类:
外连接:左外连接、右外连接
内连接:等值连接、非等值连接、自连接
全连接:(很少用)
实例:
1.当两张表进行链接查询时,没有任何限制会怎么??
案例:查询每个员工所在部门的名称?
select ename, deptno from emp;
select * from dept;
如果两张表连接没有任何条件限制:
select ename,dname from emp, dept;
56=14*4;
当两张表进行连接查询时,没有任何条件限制的时候,最终查询结果条数是两张表条数的乘积,这种现象被称为笛卡尔现象。
怎么避免?
连接时,加上条件进行筛选,
select ename,dname from emp,dept where emp.deptno=dept.deptno;
注意:查询结果是14条,但是匹配次数并没有减少。
改进:select emp.ename,dept.dname from emp,dept where emp.deptno=dept.deptno;
连接的表越多,效率越低,需要尽量避免。
内连接—等值连接
Sql92:select e.ename,d.dname from emp e,dept d where e.deptno =d.deptno;
缺点:结构不清晰,表的连接条件,和后期进一步筛选的条件都放到了where后面。
Sql99: select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno;
sql99优点:表连接的条件是独立的,如果还需要进一步筛选,则在后面继续添加where语句。
SQL99语法:
select … from a join b on a和b的连接条件 where 筛选条件。
内连接—非等值连接
找出每个员工的薪资等级,要求显示员工名、薪资、薪资等级:
select e.ename,e.sal ,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;
内连接—自连接
查询员工的上级领导,要求显示员工和其领导:
select a.ename as ‘员工名’,b.ename as ‘领导名’ from emp a join emp b on a.mgr=b.empno;
技巧:一张表看成两张表。
外连接和内连接的区别:
内连接:select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno;
内连接的特点:完全能够匹配的上这个条件的数据查询出来。
如果没有员工的部门也要查出来怎么办??
使用右外连接:
select e.ename,d.dname from emp e right join dept d on e.deptno =d.deptno;
right表示什么含义:表示将join 关键字右边的表看做是主表,主要是为了将这张表的数据全部查询出来,捎带着关联查询左边的表。在外连接当中,两张表连接,产生了主次关系。
左外连接
select e.ename,d.dname from dept d left join emp e on e.deptno =d.deptno;
任何左外都可以右外,任何右外也可以写成左外。
select e.ename,d.dname from dept d left outer join emp e on e.deptno =d.deptno;
(其中的outer是可以省略的)
思考?外连接的结果查询结果条数一定是大于内连接的查询条数吗??
是的。
三张表连接:
语法:
select …
from a…
join b
on a和b的连接条件
join c
on a和c的连接条件
join d
on a和d的连接条件
注意:一条sql语句中内连接和外连接都可以混合,都可以出现。
1.找出每个员工的部门名称以及工资等级,要求显示员工名、部门名、薪资、薪资等级:
select
e.ename,e.sal,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;
2.找出每个员工的部门名称以及工资等级,上级领导,要求显示员工名、领导名、部门名、薪资、薪资等级:
select e.ename,d.dname,e.sal,s.grade,l.ename
from emp e
join dept d
on e.deptno=d.deptno
join salgrade s
on e.sal between s.losal and s.hisal
left join emp l
on e.mgr=l.empno;
select 语句中嵌套select语句,被嵌套的select 语句被称为子查询。
子查询可以出现在什么位置??
select…(select) from…(select) where…(select).
1.where子句中出现子查询
找出比最低工资高的员工姓名和工资
select ename,sal from emp where sal>(select min(sal) from emp);
2.from子句
注意:from后面的子查询,可以将查询结果当做一张临时表
找出每个岗位的平均工资的薪资等级:
第一步:找出每个工作岗位的平均工资:select job,avg(sal) from emp group by job;
第二步:将以上查询结果当做一个新表t;
第三步:找出对应等级:select t.job,t.avgsal, s.grade from (select job,avg(sal) as avgsal from emp group by job) as t join salgrade s on t.avgsal between s.losal and s.hisal ;
3.select 后面出现子查询
找出每个员工的部门名称,要求显示员工名,部门名:
select e.ename,(select d.dname from dept d where e.deptno=d.deptno) as dname from emp e;
注意:select后面的子查询只能一次返回一条结果,多余一条就报错。