Oracle學習第七天

高級查詢

1.分組查詢
①概念
分組函數作用於一組數據,並對一組數據返回一個值。
②分組函數的使用
分組函數
avg()、sum()、min()、max()、count()
、wm_concat():行轉列
select avg(sal),sum(sal)from emp;
select max(sal),min(sal)from emp;
select count(*) from emp;
distinct:去除重複的記錄
select count(distinct deptno) from emp;
select deptno,wn_concat(ename) from emp group by deptno;
注:分組函數會自動忽略空值
③使用group by子句數據分組
--求出員工表中各部門的平均工資
select deptno,avg(sal) from emp group by deptno;
--多個分組
select deptno,job,sum(sal) from emp group by deptno,job;
④使用having子句過濾分組結果集
select deptno,avg(sal) from emp group by deptno having avg(sal)>2000
注:不能在where子句中使用組函數
having:先分組 後過濾
where: 先過濾 後分組
⑤在分組查詢中使用order by子句
order by 序號/字段
分組函數嵌套
求部門平均工資的最大值
select max(avg(sal)) from emp group by deptno
⑥group by語句的增強
select deptno,job,sum(sal) from emp group by deptno,job
select deptno,sum(sal) from emp group by deptno
select sum(sal) from emp 



select deptno,job,sum(sal) from emp group by rollup(deptno,job)


語法
group by rollup(a,b)
等價於
group by a,b
+
group by a 
+
group by null
⑦sqlplus的報表功能
報表包括:標題、頁碼、別名等
ttitle col 15 '我的報表' col 35 sql.pno
col deptno heading 部門號
col job heading 職位
col sum(sal) heading 工資總額
break on deptno skip 1
2.多表查詢
①概念
多個表中獲取數據
②笛卡爾集
列相加 行相乘


爲了避免笛卡爾集,可以在where加入有效的連接條件
在實際運行環境下,應避免使用笛卡爾全集

③連接類型
等值連接
連接條件是=號
不等值連接
連接條件是>,>=,<,<=,<>號
外連接
部門統計員工人數,顯示部門號,部門名稱,人數
select d.deptno,d.dname,count(e.empno)
from emp e, dept d where e.deptno(+)=d.deptno[(+)]
group by d.deptno,d.dname;
注:通過外連接,把對於連接條件不成立的記錄,仍然包含在最後的結果中
左外連接:當連接條件不成立的時候,等號左邊的表仍然被包含
右外連接:當連接條件不成立的時候,等號右邊的表仍然被包含

自連接
--查詢員工姓名和員工老闆的姓名
注:核心-》通過別名,將同一張表視爲多張表
select e.ename 員工姓名,b.ename 老闆姓名
from emp e,emp b
where e.mgr=b.empno;
④自連接存在的問題
不適合操作大表-->解決辦法:層次查詢

⑤層次查詢
某些情況下,可以替代自連接
本質上,是一個單表查詢


select level(僞列) empno,ename,sal,mgr
from emp 
connect by prior empno=mgr( 上一層的員工號-老闆號)
start with empno=7839(遍歷起始位置)(根節點表示方式mgr is null)
order by 1;

3.子查詢
①作用
解決 不能一步求解的問題
②需要注意的10個問題
子查詢語法中的小括號
子查詢放入小括號中
子查詢的書寫風格
可以使用子查詢的位置:where,select ,having,from
(select 後面的子查詢必須是單行子查詢)
不可以使用子查詢的位置:group by

強調:from後面的子查詢
主查詢和子查詢可以不是同一張表
一般不在子查詢中使用排序 但是在top_N分析問題中,必須對子查詢排序
例:找到員工表中工資最高的前三名
注意:行號永遠按照默認的順序生成
行號只能使用<,<=;不能使用>,>=
正確:select rownum,empno,ename,sal from (select * from emp order by sal desc) where rownum<=3
錯誤:select rownum,empno,ename,sal from emp
where rownum<=3 order by sal desc;
一般先執行子查詢,再執行主查詢;但相關子查詢例外
相關子查詢:找到員工表中薪水大於本部門平均薪水的員工
select empno,ename,sal,(select avg(sal) from emp where deptno=e.deptno) avg sal from emp e where sal>(select avg(sal) from emp where deptno=e.deptno);
單個子查詢只能使用單行操作符;多行子查詢只有使用多行操作符
多行操作符:
in(等於列表中的任何一個)、any(和子查詢返回的任意一個值比較)、all(和子查詢返回的所有值比較)
select * from emp where sal>any(select sal from emp where deptno=30)等價於
select * from emp where sal>(select min(sal) from emp where deptno=30);

select * from emp where sal>all(select sal from emp where deptno=30)等價於
select * from emp where sal>(select max(sal) from emp where deptno=30);

注意:子查詢中是null的問題
看是否是空值用 is null
--查詢不是老闆的員工
select * from emp where empno not in(select mgr from emp where egr is not null)

4.綜合示例
①分頁查詢顯示員工信息:顯示員工號,姓名,月薪(每頁顯示四條記錄,顯示第二頁的員工,按照月薪降序排列)
分頁查詢:
select r,empno,ename,sal
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;
②找到員工表中薪水大於本部門平均薪水的員工
1.
select empno,ename,sal,(select avg(sal) from emp where deptno=e.deptno) avg sal from emp e where sal>(select avg(sal) from emp where deptno=e.deptno);
2.
select e.empno,e.ename,e.sal,d.avgsal
from emp e,(select deptno,avg(sal) avgsal from emp group by deptno) d
where e.deptno=d.deptno and e.sal>d.avgsal;

生成執行計劃 
explain plan for + sql語句
執行生成計劃
select * from table(dbms_xplan.dispaly);
③按部門統計員工人數,按照格式輸出
select count(*) Total,
sum(decode(to_char(hiredate,'YYYY'),'1980',1,0)) "1980",
sum(decode(to_char(hiredate,'YYYY'),'1981',1,0)) "1981",
sum(decode(to_char(hiredate,'YYYY'),'1982',1,0)) "1982",
sum(decode(to_char(hiredate,'YYYY'),'1987',1,0)) "1987"
from emp;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章