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')
集合運算兩邊查詢的字段數量、字段類型、順序必須一致
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章