Oracle復雜查詢
數據分組,
分組函數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';
