多表查询
多表连接基本查询
使用一张以上的表做查询就是多表查询
select * from tab1,tab2
这样会出现的结果就是:笛卡儿积
连接查询的时候一般在需要连接的表中会出现相同名称的字段,按照之前表与表之间的设模式来讲,都会设置主外键关联,但是这种关联现在不太推荐使用。
select * from tab1,tab2 where tab1.field=tab2.field
这样就避免了产生 笛卡儿积
多表查询的时候我们也可以为每一张表起别名
select * from tab1 t1,tab2 t2 where t1.field= t2.field
指定查询结果要显示的字段
select t1.name,t1.age,t2.field from tab1 t1,tab2 t2 where t1.field= t2.field
自关联查询
顾名思义,自关联查询就是自己关联自己。我们在安装Oracle之后,scoot用户下有一张员工表可以供我们练习查询。
需求: 查询每个员工的上级领导
分析: emp 这张表中 mgr字段是当前员工的上级领导的编号,所以该字段就对emp表产生了关联 。这个时候我们就要用到自关联查询。
select e1.empno, e1.ename,e2.empno,e2.ename from emp e1,emp e2 where e1.mgr = e2.empno
外连接查询
包含右表中所有数据,以及左表的关联数据
select e.empno,e.ename,d.deptno,d.dname from emp e,dept d where e.deptno(+)=d.deptno
使用(+)表示左连接或者是右连接
但是由于(+)是Oracle独有的书写方法,个人推荐使用left join 与 right join
子查询
子查询(内查询):在主查询之前一次执行完成
子查询的结果被主查询使用
子查询的类型:
单行子查询:只返回一条记录
# 单行子查询示例1
select ename,job,sal from emp where
job = (select job from emp where empno = 7566)
and sal >(select sal from emp where empno = 7782)
# 单行子查询实例2
select ename,job,sal from emp where sal = (select min(sal) from emp);
多行子查询:
返回了多条记录
多行操作符
单行子查询中的null值问题
select ename,job,sal from emp where
job = (select job from emp where ename = 'Mike')
多行子查询中Null值的问题
# 查询不是老板的员工
select * from emp where empno not in(select mgr from emp);
Exists用法
语法 exists(sql查询语句)
一: 判断exists后面的sql语句是否为真
sql语句查询为空 返回值是false
slq查询语句有值 返回值就是true
select * from dept;
select * from dept where 1 = 1;
select * from emp where exists(select * from dept where 1 = 1)
select * from emp where exists(select * from dept where deptno = 10)
二:判断一个表中是否含有另一张表中外键的记录
# 查询有员工的部门
select * from dept d where exists (select * from emp e where e.deptno = d.deptno)
Oracle中的分页查询
ROWNUM:表示行号,实际上此是一个列,但是这个列是一个伪列,此列可以在每张表中出现
ROWID:表中没行数据指向磁盘上的物理地址
集合运算
并集 :union / union all 返回两个集合中所有的记录 包括重复的
# 工资大于1500 或者是20号部门下的员工
select * from emp where sal > 1500 union select * from emp where deptno = 20
交集:intersect 返回同时属于两个集合的记录
#工资大于1500 并且是20号部门下的员工
select * from emp where sal > 1500 intersect select * from emp where deptno = 20
差集:minus 返回属于第一个集合但是不属于第二个集合的记录
# 查询1981年入职的普通员工 (不包含总裁和经理)
select * from emp where to_char(hiredate,'yyyy')='1981'
minus
select * from emp where job = 'PRESIDENT'or job='MANAGER'