四、Oracle的復雜查詢


Oracle復雜查詢

數據分組,

分組函數max, min, avg, sum, count

  1. 查詢工資最高的人的姓名

select ename from emp where sal = (select max(sal) from emp);

  1. 給所有低於平均工資的員工薪水上漲10%

update emp set sal = (select avt(sal) from emp)*10% where sal<(select avt(sal) from emp);

grout by 和 having 字句

groupt by用於對查詢結果分組統計

having子句用於限制分組結果顯示

  1. 如何顯示每個部門的平均工資和最高工資

select avg(sal),max(sal), deptno from emp group by deptno;

  1. 顯示每個部門的每種崗位的平均工資和最低工資

select avg(sal),min(sal),deptno,job from emp group by deptno,job;

  1. 顯示平均工資低於2000的部門和號和它的平均工資

select deptno,avg(sal) from emp group by deptno having avg(sal)>2000;

 

總結:

  1. 分組函數(max,min,avg,count)只能出現在選擇列表(select后),having和order by子句中
  2. 如果select語句中同時包含group by,having和order by,他們的順序必須是group by,having和order by
    (先分組→再抑制結果顯示→最后分組)
  3. 在選擇列中如果有列,表達式和分組函數,那么這些列和表達式必須有一個出現在group by子句中,否則就會報錯。如deptno

 

多表查詢

  1. 顯示雇員名,雇員工資和雇員所在部門的名稱

select a1.ename,a1.sal,a2.dname from emp a1,dept a2 where a1.deptno=a2.deptno;

笛卡爾積,原則:多表查詢的條件是至少不能少於表的個數-1

  1. 如何顯示部門號為10的部門名、員工名和工資

select b.dname, a.ename,a.sal from emp a,dept b where b.deptno=a.deptno and a.deptno=10;

——先把2張表連上,再用用紅色條件過濾掉

  1. 顯示各個員工的姓名、工資及其工資的級別

select a1.ename,a1.sal,a2.grade from emp a1, salgrade a2 where a1.sal between a2.losal and a2.hisal;

  1. (擴展)顯示雇員名、雇員工資以及所在部門的名字並按部門排序

select a1.ename,a1.sal,a2.dname from emp a1,dept a2 where a1.deptno = a2.deptno order by a1.deptno;

——多表排序

 

自連接

自連接是指在同一張的連接查詢

  1. 顯示某個員工上級領導的姓名。如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中方式

  1. rownum 先做一個子查詢

select * from emp

  1. 顯示rownum[rownum是Oracle分配的]

select a1.*,rownum rn from (select * from emp) a1;

查詢結果就會多出一列,rn,表示rownum,行號數,是Oracle分配的。

  1. 顯示想要選取的行數據

select a1.*,rownum rn from (select * from emp) a1 where rownum<=10;

and rownum>=6;(rownum不能使用2次,否則查不出數據)

到此,可以顯示1-10行數據,已經砍掉一大半了,目標是顯示6-10行數據。

  1. 再做一次子查詢

select * form (select a1.*,rownum rn from (select * from emp) a1 where rownum<=10) a2 where rn>=6;

結果才是想要的6-10行數據。

 

注意,幾個查詢變化:

  1. 如果要指定查詢列,而不是查詢所有列,只需修改最里層的子查詢即可;
  2. 排序也只需修改最里層的子查詢就可。
  3. 同理,分組啊,再排序啊,統統的改動最里層的子查詢即可。

 

 

 

 

 

用查詢結果創建一張新表

這個命令是一種快捷的建表方式

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操作符

  1. Union 兩個集合取或的操作,去掉重復行

該操作符用於取得2個結果集的並集。當使用該操作符時,會自動去掉結果集中的重復行。

select ename,sal,job from emp where sal>2500 union

select ename,sal,job from emp where job='MANAGER';

  1. Union all 並的操作,不去掉重復行

該操作符與union類似,但是不會取消重復行,不會排序

  1. intersect 合並查詢

該操作符取2個集合的交集

  1. minus 差集操作

該操作符取2個集合的差集

 

創建數據庫的方法

  1. 通過Oracle提供的向導工具

Database Configration Assistant(DBCA)Oracle數據庫配置助手

  1. 手工代碼直接創建

 

 

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';


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM