oracle_多表_分页_集合查询

1.解决笛卡尔集的问题:


select * from emp e,dept d where e.deptno=d.deptno;




2.内连接:
隐式内连接:select * from emp e,dept d where e.deptno=d.deptno;
显式内连接:select * from emp e inner join dept on e.deptno=d.deptno;

3.外连接:
左外连接:select * from A left join B on A.列=B.列;
右外连接:select * from B right join A on A.deptno=B.deptno;

4.oracle特有外连接:


使用符号(+):放在作为补充显示的列后面

(+)=:放在了等号的左边,表示的是右外连接 Select * from A,B where A.列(+)=B.列


=(+):放在了等号的右边,表示的是左外连接 Select * from A,B where A.列=B.列(+)


5.oracle自连接:(把emp表当作是员工表和领导表)


select * from emp e,emp m where e.mgr=m.empno;


6.多表查询推荐方式:


select e.ename,e.job,e.sal,m.ename,d.dname,
decode(s1.grade,1,'第一级',2,'第二级',3,'第三级',4,'第四级','第五级'),
decode(s2.grade,1,'第一级',2,'第二级',3,'第三级',4,'第四级','第五级')
 from emp e
left join emp m on e.mgr=m.empno
left join dept d on e.deptno=d.deptno
left join salgrade s1 on e.sal between s1.losal and s1.hisal
left join salgrade s2 on m.sal between s2.losal and s2.hisal


7. 查询比雇员7654工资高并和7788相同职位的员工:


select * from emp e where e.sal>(select sal from emp where empno='7654') and e.job=(select job from emp


where empno='7788')


8. 子查询放在select中(部门名称)




select e.*,(select d.dname from dept d where e.deptno=d.deptno) from emp e;




9. 查询每个部门的最低工资和最低工资的员工



select e.ename,e.sal,d.dname,d.deptno
 from emp e,(select deptno,min(sal) sal from emp e
group by deptno) dm,dept d where
e.deptno=d.deptno and e.deptno=dm.deptno and e.sal=dm.sal;




10. 查询不是领导的所有员工信息(not in)


select * from emp where empno not in(select mgr from emp where mgr is not null)




11. 查询每个部门的最低工资和最低工资的员工


select e.ename,e.sal,d.dname from emp e,(select deptno,min(sal) sal from emp  group 


by deptno) dm,dept d where e.deptno = d.deptno and e.deptno=dm.deptno and 
e.sal = dm.sal;


12. exists
判断结果集是否存在 语法:where exists(sql语句)
用来判断结果集是否存在,如果存在返回true
如果不存在返回false


select * from emp where exists(select * from dept where 1=1 )结果和select * from emp
select * from emp where exists(select * from dept where 1=2 )结果为null


 查询有员工的部门信息
Select * from dept where deptno in 
(select deptno from emp where deptno is not null)




13.分页实现:


Mysql:limit
Sqlserver:top
Sybase:top(分页实现不了)
Db2:rownum
Oracle:使用rownum伪列实现的


 Rownum的实现原理
1、执行查询语句
2、提取第一条记录赋值rownum为1
3、判断该行记录是否满足条件,如果不满足就放弃该行,如果满足返回该行(如果放弃那么rownum继续会从1开始生成)
4、继续提取记录,生成rownum
5、重复步骤3




 查询员工信息的前三条
Select rownum,emp.* from emp where rownum<5




先使用子查询生成临时数据集,再用rownum过虑
Select * from (select rownum r , emp.* from emp ) t where t.r>5


找到员工表中工资最高的前三名:


select e2.* from (select rownum,e.* from emp e   order by sal desc) e2 where rownum <4;




提取出6到10条记录(第二页)
select * from ( select rownum rm,t.* from ( select * from emp order by sal desc) t)
where rm>5 and rm < 11;


select * from ( select rownum rm,t.* from ( select * from emp order by sal desc) t where rownum < 11)
where rm>5;(效率高)
 


 14. 找到员工表中薪水大于本部门平均薪水的员工
 
  select e.ename,e.empno,e.sal,d.deptno from (select avg(sal) sal,deptno from emp group by deptno) d,emp e
 where e.sal > d.sal and e.deptno=d.deptno;
 
 
 15. 统计每年入职的员工个数
 
  select to_char(e.hiredate,'yyyy') hire_year, count(*)  from emp e
 group by to_char(e.hiredate,'yyyy');
 
 
 Select 
Sum(hire_count) total,
sum(decode(t.hire_year,'1980',t.hire_count)) "1980",
sum(decode(t.hire_year,'1981',t.hire_count)) "1981",
sum(decode(t.hire_year,'1982',t.hire_count)) "1982",
sum(decode(t.hire_year,'1987',t.hire_count)) "1987"
from 
(Select to_char(hiredate,'yyyy') hire_year,count(*) hire_count
From emp group by to_char(hiredate,'yyyy')) t




16, 查询工资大于1500 或是20号部门的员工


普通实现:
 select * from emp where sal > 1500 or deptno=20;


并集函数实现:
 select * from emp where sal > 1500
 union
 select * from emp where deptno=20
 
  select * from emp where sal > 1500
 union all
 select * from emp where deptno=20
 
 并集(取两个集合最大的范围)
Union A(1,2,3) B(2,3,4) A并B的结果(1,2,3,4)
Union all  A(1,2,3) B(2,3,4) A并B的结果(1,2,3,2,3,4)


 
17.查询工资大于1500并且是2号部门的员工


普通实现:
 select * from emp where sal > 1500 and deptno=20;
 
 交集函数实现:
 
 select * from emp where sal > 1500
 intersect
 select * from emp where deptno=20
 
18. 1981年入职的普通员工,不包含总裁和经理


普通实现:
 select * from emp where job not in('MANAER','PRESIDENT') and to_char(hiredate,'yyyy')='1981'


差集(Minus从一个集合去掉两个集合公共的部分)


Select * from emp where to_char(hiredate,'yyyy')='1981' 
Minus
Select * from emp where job in ('MANAGER','PRESIDENT')
集合运算两边查询的字段数量、字段类型、顺序必须一致
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章