標籤:
資料分組,
分組函數max, min, avg, sum, count
- 查詢工資最高的人的姓名
select ename from emp where sal = (select max(sal) from emp);
- 給所有低於平均工資的員工薪水上漲10%
update emp set sal = (select avt(sal) from emp)*10% where sal<(select avt(sal) from emp);
grout by 和 having 字句
groupt by用於對查詢結果分組統計
having子句用於限制分組結果顯示
- 如何顯示每個部門的平均工資和最高工資
select avg(sal),max(sal), deptno from emp group by deptno;
- 顯示每個部門的每種崗位的平均工資和最低工資
select avg(sal),min(sal),deptno,job from emp group by deptno,job;
- 顯示平均工資低於2000的部門和號和它的平均工資
select deptno,avg(sal) from emp group by deptno having avg(sal)>2000;
總結:
- 分組函數(max,min,avg,count)只能出現在挑選清單(select後),having和order by子句中
- 如果select語句中同時包含group by,having和order by,他們的順序必須是group by,having和order by
(先分組→再抑制結果顯示→最後分組)
- 在選擇列中如果有列,運算式和分組函數,那麼這些列和運算式必須有一個出現在group by子句中,否則就會報錯。如deptno
多表查詢
- 顯示僱員名,僱員工資和僱員所在部門的名稱
select a1.ename,a1.sal,a2.dname from emp a1,dept a2 where a1.deptno=a2.deptno;
笛卡爾積,原則:多表查詢的條件是至少不能少於表的個數-1
- 如何顯示部門號為10的部門名、員工名和工資
select b.dname, a.ename,a.sal from emp a,dept b where b.deptno=a.deptno and a.deptno=10;
——先把2張表連上,再用用紅色條件過濾掉
- 顯示各個員工的姓名、工資及其工資的層級
select a1.ename,a1.sal,a2.grade from emp a1, salgrade a2 where a1.sal between a2.losal and a2.hisal;
- (擴充)顯示僱員名、僱員工資以及所在部門的名字並按部門排序
select a1.ename,a1.sal,a2.dname from emp a1,dept a2 where a1.deptno = a2.deptno order by a1.deptno;
——多表排序
自串連
自串連是指在同一張的串連查詢
- 顯示某個員工上級領導的姓名。如Ford
select a.ename from emp a where a.mgr = a.empno and a.ename = ‘Ford‘;
select worker.ename, boss.ename from emp worker, emp boss where worker.mgr = boss.empno and worker.ename = ‘FORD‘;
——小竅門:把一張表想象成2張不同的表,起別名,然後就好做了。
子查詢
子查詢是指嵌入在其它sql語句中的select語句。也叫巢狀查詢。
單行子查詢
單行子查詢是指只返回一行資料的查詢語句;
例如:如何顯示與SMITH同一部門的所有員工
select a.ename from emp a where a.deptno = (select deptno from emp b where b.ename=‘ SMITH‘);
多行字查詢
多行子查詢是指返回多行資料的查詢語句
例如:如何查詢和部門10的工作相同的僱員名字、崗位、工資和部門號
select * from emp a where a.job in (select distinct job from emp where emp.deptno = 10);
在多行子查詢中使用all操作
例如:如何顯示工資比部門30的所有員工的工資高的員工姓名、工資和部門號
方法1:
select ename,sal,deptno from emp where sal >all (select sal from emp where deptno=30);
方法2:
select ename,sal,deptno from emp where sal > (select max(sal) from emp where deptno=30);
比較:
方法2效率要遠高於方法1,因為方法1會一條一條的比較;方法2直接比較結果。
在多行子查詢中使用any操作符
例:顯示工資比部門30的任意一個員工的工資高的員工的姓名、工資和部門號
方法1:
select a.ename,a.sal,a.deptno from emp a where a.sal > any(select sal from emp where deptno=30);
方法2:
select ename,sal,deptno from emp where sal > (select min(sal) from emp where deptno=30);
多列子查詢
單行子查詢是指子查詢返回單行、單列資料;
多行子查詢是指子查詢返回多行、單列資料。都是針對單列而言的;
而多列子查詢則是指子查詢返回多個列的子查詢語句。
例如:查詢與Smith部門和崗位完全相同的所有僱員。
select * from emp where (deptno,job)=(select deptno,job from emp where ename=‘SMITH‘);
from子句中使用子查詢
例子:顯示高於自己部門平均工資的職員資訊
1)查詢各個部門的平均工資和部門號
select deptno, avg(sal) from emp group by deptno;
2)查詢自己部門的
把上面的查詢看做是一張子表, (select deptno, avg(sal) from emp group by deptno) a1
select a2.ename,a2.sal,a2.deptno,a1.avgSal from emp a2, (select deptno, avg(sal) avgSal from emp group by deptno) a1 where a2.deptno=a1.deptno and a2.sal > a1.avgSal;
總結:當在from子句中使用子查詢時,該子查詢會被作為一個視圖對待,因此叫做內嵌視圖,當在from子句中使用子查詢時,必須給子查詢指定別名。
——給列取別名可以使用as,但是給表、視圖、子查詢起別名不可以用as
分頁
Oracle的分頁是最複雜的,要使用2次子查詢,但效率也是最高的,因為內部使用了2分尋找的原理。MySql的分頁是最簡單的,直接一個limit就實現了;SqlServer次之。
Oracle的分頁一共有3中方式
- rownum 先做一個子查詢
select * from emp
- 顯示rownum[rownum是Oracle分配的]
select a1.*,rownum rn from (select * from emp) a1;
查詢結果就會多出一列,rn,表示rownum,行號數,是Oracle分配的。
- 顯示想要選取的行資料
select a1.*,rownum rn from (select * from emp) a1 where rownum<=10;
and rownum>=6;(rownum不能使用2次,否則查不出資料)
到此,可以顯示1-10行資料,已經砍掉一大半了,目標是顯示6-10行資料。
- 再做一次子查詢
select * form (select a1.*,rownum rn from (select * from emp) a1 where rownum<=10) a2 where rn>=6;
結果才是想要的6-10行資料。
注意,幾個查詢變化:
- 如果要指定查詢列,而不是查詢所有列,只需修改最裡層的子查詢即可;
- 排序也只需修改最裡層的子查詢就可。
- 同理,分組啊,再排序啊,統統的改動最裡層的子查詢即可。
用查詢結果建立一張新表
這個命令是一種快捷的建表方式
create table myTable(id,name,sal,job,deptno) as select empno,ename,sal,job,deptno from emp;
命令執行後,myTable不僅表結構和emp一樣,連資料都全部從emp表中倒入了。
合并查詢
有時在實際應用中,為了合并多個select語句的結果,可以使用集合操作符號union、union all、intersect和minus操作符
- Union 兩個集合取或的操作,去掉重複行
該操作符用於取得2個結果集的並集。當使用該操作符時,會自動去掉結果集中的重複行。
select ename,sal,job from emp where sal>2500 union
select ename,sal,job from emp where job=‘MANAGER‘;
- Union all 並的操作,不去掉重複行
該操作符與union類似,但是不會取消重複行,不會排序
- intersect 合并查詢
該操作符取2個集合的交集
- minus 差集操作
該操作符取2個集合的差集
建立資料庫的方法
- 通過Oracle提供的嚮導工具
Database Configration Assistant(DBCA)Oracle資料庫配置助手
- 手工代碼直接建立
Java操作Oralce,jsp與分頁
.Net操作Oracle,分頁
使用特定格式插入日期值
使用to_date()函數,按照年-月-日的格式插入日期
to_date(‘1989-05-11‘,‘yyyy-mm-dd‘)
可以格式化日期值
使用子查詢插入資料
當使用values子句時,一次只能插入一行資料,當使用子查詢插入資料時,一條insert語句可以插入大量的資料。當處理行遷移,資料移轉或者裝載外部表格的資料到資料庫時,可以使用子查詢來插入資料。
insert into myTable(id,name,deptno) select (myId,ename,eno) from emp where eno=10;
使用子句更新資料
使用update子句更新資料時,即可以使用運算式或者數值直接修改資料,也可以使用子查詢修改資料
例如:希望更新員工scott的崗位、工資、補助與員工simth一樣
update emp set (job,sal,comm) = (select job,sal,comm from emp where enma =‘smith‘) where ename=‘scott‘;
Oracle複雜查詢