表emp:
表dept:
表salgrade:
92语法
查询雇员名称和部门对应的名称:
select e.ename,d.dname
from emp e,dept d
where e.deptno = d.deptno;
输出:
这种关联查询叫做 等值连接,即两个表中包含相同的列名。
查询雇员名称和自己的薪水等级:
select e.ename,sg.grade
from emp e,salgrade sg
where e.sal between sg.losal and sg.hisal;
两个表中没有相同的列名,但是某一列在另一张表的列的范围内,此为非等值连接。
左外连接/右外连接
–需要将雇员表中的所有数据都进行显示,利用等值连接的话只会把关联到的数据显示,
–没有关联到的数据不会显示,此时需要外连接
–分类:左外连接(把左表的全部数据显示)和右外连接(把右表的全部数据显示)
select * from emp e,dept d where e.deptno = d.deptno;--等值连接
select * from emp e,dept d where e.deptno = d.deptno(+);--左外连接
select * from emp e,dept d where e.deptno(+) = d.deptno;--右外连接
自连接
–自连接,将一张表当成不同的表来看待,自己关联自己
–将雇员和他经理的名称查出来
select e.ename,m.ename from emp e,emp m where e.mgr = m.empno;
笛卡尔积
–当关联多张表,但是不指定连接条件的时候,会进行笛卡尔积,
–关联后的总记录条数为M*n,一般不要使用
select * from emp e,dept d;
99语法
CROSS JOIN
NATURAL JOIN
USING子句
ON子句
LEFT OUTER JOIN
RIGHT OUTER JOIN
FULL OUTER JOIN
Inner join
--cross join 等同于92语法中的笛卡儿积
select * from emp cross join dept;
--natural join 相当于是等值连接,但是注意,不需要写连接条件,会从两张表中找到相同的列做连接
--当两张表中不具有相同的列名的时候,会进行笛卡儿积操作,自然连接跟92语法的自连接没有任何关系
select * from emp e natural join dept d ;
select * from emp e natural join salgrade sg;
--on子句,可以添加任意的连接条件,
--添加连接条件 相当于92语法中的等值连接
select * from emp e join dept d on e.deptno = d.deptno;
--相当于92语法中的非等值连接,
select * from emp e join salgrade sg on e.sal between sg.losal and sg.hisal;
--left outer join ,会把左表中的全部数据正常显示,右表没有对应的数据直接显示空即可
select * from emp e left outer join dept d on e.deptno = d.deptno;
select * from emp e,dept d where e.deptno = d.deptno(+);
--right outer join ,会把右表中的全部数据正常显示,左表中没有对应的记录的话显示空即可
select * from emp e right outer join dept d on e.deptno = d.deptno;
select * from emp e,dept d where e.deptno(+) = d.deptno;
--full outer join ,相当于左外连接和右外连接的合集
select * from emp e full outer join dept d on e.deptno = d.deptno;
--inner outer join,两张表的连接查询,只会查询出有匹配记录的数据
select * from emp e inner join dept d on e.deptno = d.deptno;
select * from emp e join dept d on e.deptno = d.deptno;
--using,除了可以使用on表示连接条件之外,也可以使用using作为连接条件,此时连接条件的列不再归属于任何一张表
select deptno from emp e join dept d using(deptno);
select e.deptno,d.deptno from emp e join dept d on e.deptno = d.deptno;
--总结:两种语法的SQL语句没有任何限制,再公司中可以随意使用,但是建议使用99语法,不要使用92语法,SQL显得清楚明了
子查询
--1.求平均薪水最高的部门的编号
select deptno,avg(e.sal) from emp e group by deptno;
select max(t.sal) from (select deptno,avg(e.sal) sal from emp e group by deptno) t;
select deptno
from (select deptno, avg(e.sal) sal from emp e group by deptno)
where sal =
(select max(t.sal)
from (select deptno, avg(e.sal) sal from emp e group by deptno) t);
--2.求部门平均薪水的等级
select deptno,avg(e.sal) from emp e;
select t.deptno, sg.grade
from salgrade sg
join (select e.deptno, avg(e.sal) sal from emp e group by e.deptno) t
on t.sal between sg.losal and sg.hisal;
--3.求部门平均的薪水等级
select e.ename,e.sal,e.deptno,sg.grade
from salgrade sg,emp e
where e.sal between sg.losal and sg.hisal;
select avg(t.grade),deptno
from (select e.ename,e.sal,e.deptno,sg.grade
from salgrade sg,emp e
where e.sal between sg.losal and sg.hisal) t
group by deptno;
--4.求薪水最高的前5名雇员
select * from emp e order by e.sal desc;
select * from (select * from emp e order by e.sal desc) where rownum <= 5;
--5.求薪水最高的第6到第10名雇员
select t1.*, rownum rn from (select * from emp e order by e.sal desc) t1 where rownum<=10;
select *
from (select t1.*, rownum rn
from (select * from emp e order by e.sal desc) t1
where rownum <= 10) t
where t.rn > 5
and t.rn <= 10;