1. 程式人生 > >oracle關聯查詢與子查詢例子

oracle關聯查詢與子查詢例子

--分組查詢
--分組函式作用於一組資料,並對一組資料返回一個值
--常用分組函式
--avg  sum  min  max  count  wm_concat
wm_concat(行轉列)
select deptno 部門號,wm_concat(ename) 部門中員工的姓名 
	from emp groupt by deptno;
結果:
10號部門  張,黃,蔣...
20號部門  羅, 劉,卜...

--統計員工的平均工資(查詢所有員工工資再除以員工人數以求平均數)
--分組函式會自動忽略空值
select avg(sal)  from emp;
--求每個部門的平均工資,顯示:部門號,部門的平均工資
select deptno,avg(sal) from emp group by deptno;
--所有select 列表中所有未包含在組函式中的列都應該包含在group by子句中
select a,b,c,avg(sal) from emp group by a,b,c;
--(先按照a分組,如果a相同,再按照b分組,以此類推) 

--過濾分組having 
select depton,avg(sal) from emp group by depton having avg(sal) > 2000;
--查詢10號部門的平均工資
--儘量使用where(效率更高)where:先過濾再分組  having:先分組再過濾
select depton,avg(sal) from emp group by depton having depton = '10';
select depton,avg(sal) from emp where depton = '10' group by depton;

--order by 
select depton,avg(sal) from emp group by depton order by avg(sal);

--分組巢狀(求部門平均工資的最大值)
select depton,max(avg(sal)) from emp group by depton;

--group by 語句的增強rollup();
(
select depton,job,sum(sal) from emp group by depton,job;
select depton,job,sum(sal) from emp group by depton;
select depton,job,sum(sal) from emp;
)
--相當於上述三個語句的結果集
select depton,job,sum(sal) from emp group by rollup(depton,job);


--------------------------
--------------------------
多表查詢
內連線,外連線,自連線,層次查詢,等值連線,不等值連線
--笛卡爾集  如a表有10條資料,b表有10條資料,則關聯結果為100條資料
select * from a,b;
--等值連線
select e.empno from emp e,dept d where e.deptno = d.deptno;

--左外連線
--當連線條件不成立的時候,等號左邊的表仍然被包含
--(以左表資料為主,保留左邊全部資料)

--右外連線
--當連線條件不成立的時候,等號右邊的表仍然被包含
--(以右表資料為主,保留右邊全部資料)

--外連線
--即" (+)"所在位置的另一側為連線的方向,通常將全量集合與部分集合連線時,在部分集合的列後面帶上(+)
SELECT a.*, b.* from a(+) = b就是一個右連線,
等同於
select a.*, b.* from a right join b

SELECT a.*, b.* from a = b(+)就是一個左連線,
等同於
select a.*, b.* from a left join b

--自連線(不適合操作大表)
--查詢老闆下面有哪些員工,相同的一個表,不同的別名,當兩個表看
select boss_name,emp_name from emp a, emp b where a.boss_no = b.emp_no

--層次查詢(解決自連線資料量過多的情況)
--類似於樹結構 
select level,empno,ename,sal from emp 
	connect by prior emp_no = boss_no 
		start with boss_no is null
			order by 1;
--start with 指定從樹的哪個節點開始遍歷
--以上為從根節點開始遍歷整棵樹
--也可以從指定節點開始遍歷子樹
select * from emp connect by prior emp_no = boss_no start with emp_no = '1000'
--(從emp_no等於1000開始遍歷)



--------------------------------
--------------------------------
-- 子查詢
--查詢工資比scott高的員工
select emp_name,sal from emp
	where sal > (select sal from emp where emp_name='scott')
--使用子查詢的位置(where,select,having,from)

--select後面,必須是一個單行子查詢,只返回一條記錄 
select empno,ename,sal,(select job from emp where empno = '1010')
	from emp;
--having後面
select deptno,avg(sal) from emp 
	group by deptno 
		having avg(sal) > (select max (sal)
								from emp where deptno = '1010')
--from後面(可以將子查詢的結果當成是一張新的表)
select * from (select empno,ename,sal from emp)
--子查詢和子查詢可以不是同一張表
select * from emp where deptno = (
								select deptno from dept where dname = 'sales'	
										)
--子查詢的排序問題
--rownum行號,偽列(預設一個順序,行號不隨排序而改變  )
select rownum,empno,enmae,sal
	from emp 
		where rownum <= 3
			order by sal desc;
--外層行號為,子查詢的行號
select rownum,empno,ename,sal from (
	select * from emp order by sal desc
	)where rownum<=3;
--相關子查詢
select empno,ename,sal,(select avg(sal) from emp where deptno = e.deptno) from emp e  
	where sal > (select avg(sal) from emp 
			where deptno = e.deptno);	
--單行子查詢只能使用單行操作符;多行子查詢只能使用多行操作符
--單行子查詢,只返回一條記錄
--單行操作符
--(=  >  >=  <  <=  <>)
--多行子查詢,返回多條記錄
--多行操作符
--(in any all)
--(查詢員工資訊,要求1:職位與1010員工一樣,2:薪水大於1020員工的薪水)
select * from emp 
	where job = (select job from emp where empno='1010') and 
		  sal > (select sal from emp where empno='1020')
--查出工資最低的員工
select * from emp 
	where sal = (select min(sal) from emp);
--查詢最低工資大於20號部門最低工資的部門號和部門的最低工資
select deptno,min(sal)
	from emp 
		group by deptno
			having min(sal) > (select min(sal) from emp where deptno=20)

--多行操作符
--查詢部門名稱是sales和accounting的員工資訊
--子查詢
select * from emp where deptno in(
	select deptno from dept where dep_name ='Sales' or dep_name='accounting';
)
--表關聯
select e.*
  from emp e, dept d
 where e.deptno = d.deptno
   and d.dep_name in ('sales','accounting')

--查詢工資比30號部門任意其中一個員工高的員工資訊
select e.*
  from emp e
 where e.sal > (select min(d.sal) from emp d where d.deptno = 30)

select e.*
  from emp e
 where e.sal > any (select d.sal from emp d where d.deptno = 30)

--查詢工資比30號部門所有員工高的員工資訊
select e.*
  from emp e
 where e.sal > (select max(d.sal) from emp d where d.deptno = 30)

select e.*
  from emp e
 where e.sal > all (select d.sal from emp d where d.deptno = 30)


--子查詢中的null值問題



--分頁查詢顯示員工資訊:顯示員工號,姓名,月薪
--每頁顯示四條,按照月薪降序排列
--rownum只能使用<,<=  不能使用>,>=
select *
	from(select rownum r,empno,ename,sal 
		from (select rownum,empno,ename,sal from emp order by sal desc) e1
			where rownum<=8) e2
				where r>=5