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')
集合运算两边查询的字段数量、字段类型、顺序必须一致
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')
集合运算两边查询的字段数量、字段类型、顺序必须一致
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.