oracle 多表、分页、集合

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;

原文地址:https://www.cnblogs.com/yang1182/p/9593165.html