1、多表查询:
表连接分类: 内连接、外连接、交叉连接、自连接
(1)内连接:
语法格式:
语法1:
select *
from 表1 [inner] join 表2 on 表1.字段1=表2.字段1;
语法2:
select *
from 表1,表2
where 表1.字段1=表2.字段1;
说明:
内连接中的inner join 和 join 是等价的!但是建议为了程序的可读性
尽量不要省略inner!
(2)、外连接:
分类:左外连接、右外连接、全连接!
----------------------左外连接:left outer join
连接效果:
左侧的表中的全部数据都会被显示出来,但是右侧表的数据,
只有和左侧匹配上的字段才会被查询出来!否则都会显示null!
SQL语法格式:
语法1:
select *
from 表1 left outer join 表2
on 表1.字段1=表2.字段1;
语法2:
select *
from 表1 left outer join 表2
where 表1.字段1=表2.字段1(+);
-------------------右外连接:right outer join
连接效果:
右侧的表中的全部数据都会被显示出来,但是左侧表的数据,
只有和右侧匹配上的字段才会被查询出来!否则都会显示null!
SQL语法格式:
语法1:
select *
from 表1 right outer join 表2
on 表1.字段1=表2.字段1;
语法2:
select *
from 表1 left outer join 表2
where 表1.字段1(+)=表2.字段1;
----------------------全外连接:full/all outer join
SQL语法格式:
select *
from 表1 full outer join 表2
on 表1.字段1=表2.字段1;
(3)自连接(self join):
自连接的本意就是将一张表看成多张表来做连接。
select work.enameworker,mgr.enamemanager from scott.empwork,scott.empmgr
where work.mgr=mgr.empno
order by work.ename;
(4)交叉连接: 表与表之间做笛卡尔积查询!
SQL语法格式:(无条件查询)
select *
from 表1 cross join 表2;
或者
select *
from 表1, 表2;
2、分页查询
oracle使用rownum 是一个伪列 数据库提取记录才会生成的数值 1,2,3,4
作用是用于实现oracle的分页 必须使用子查询实现
------------执行流程(带条件)
a.查询emp表,生成emp伪表
b.成一个rownum
c.根据分页条件判断该rownum是否与该条件匹配
d.条件匹配 取出该条记录
d.生成第二个rownum重复c操作
-----------别名问题
由于rownum的where判断执行在select关键字之前,
当前查询中的rownum别名不能用于条件中做判断,别名只可以用于外部条件判断
--------------------------------------------------.rowid 是数据库保存记录时候生成的真实物理地址 唯一不变,作用: 数据库操作记录使用
提取员工表前三行:
select rownum, emp.* from emp where rownum <4;
提取4行之后的
--错误示例
select rownum,emp.* from emp where rownum >3; --错误
--生成第一个rownum,进行条件判断时不符合,无法提取结果,结束查询,结果为空--
--解决方案,先查询带rownum的伪表
select rownum,emp.* from emp
--查询伪表,选出4条以后的数据
select * from (select rownum r,emp.* from emp) re where re.r >3;
提取工资排行前三的员工(先排序:select * from emp order by sal desc --先排序
提取6----10的记录:
-扫描全表生成伪表,再进行提取分页(表数据多时效率极低)
select * from (select rownum r, e.* from emp e ) er where er.r > 5 and er.r <11;
select * from (select rownum r, e.* from emp e where rownum < 11) er where er.r > 5;
例6.排序加分页
--a排序
select * from emp order by sal desc
--b生成前10条伪表
select rownum , t1.*
from (select * from emp order by sal desc ) t1
where rownum <11
--提取6到10
select * from
(select rownum r , t1.* from (select * from emp order by sal desc ) t1
where rownum <11) t2 where t2.r >4
3、集合
集合使用
1.交集 取两个集合共同的部分 intersect A(1,2,3) B(2,3,4) A 交B (2,3)
2**.并集**
1)取两个集合所有的部分 union A(1,2,3) B(2,3,4) A 并B (1,2,3,4)
2)合并所有的数据包含重复 union all A(1,2,3) B(2,3,4) A 并B (1,2,3,2,3,4)
3.差集 从一个集合去掉另外一个集合剩余的部分 minus A(1,2,3) B(2,3,4) A 差B (1)
A 集合的使用场景:用于跨表的数据合并
B 规则 合并的①数据列数一致 ②类型一致
--例1:工资大于1500,或者是20部门下的员工
--数据源
select * from emp where sal > 1500
select * from emp where deptno =20
--or 方式
select * from emp where sal > 1500 or deptno =20
--集合方式 并集
select * from emp where sal > 1500
union
select * from emp where deptno =20
--例2:工资大于1500,并且是20部门下的员工
--and方式
select * from emp where sal > 1500
and deptno =20
/
select * from emp where sal > 1500
intersect
select * from emp where deptno =20
/
--例3:1981年入职的普通员工(不包括经理,总裁)
select * from emp where job in ('MANAGER','PRESIDENT')
select * from emp where to_char (hiredate,'yyyy') =1981
--and 方式
select * from emp where to_char (hiredate,'yyyy') =1981
and job not in ('MANAGER','PRESIDENT')
--集合方式 差集
select * from emp where to_char(hiredate,'yyyy')='1981'
minus
select * from emp where job in ('MANAGER','PRESIDENT')
--例4
--创建manager表作为公司的所有领导
create table manager (
mid number(9),
mname varchar(10)
)
select * from manager
insert into manager values(1,'zs');
insert into manager values(2,'lis');
commit;
--------查询公司的所有员工的姓名 编号 职位
--表 员工表 领导表
select mid 员工编号 ,mname 员工名称 from manager
union
select empno ,ename from emp;