ORACLE 多表連線與子查詢
Oracle表連線
SQL/Oracle使用表連線從多個表中查詢資料
語法格式:
select 欄位列表 from table1,table2 where table1.column1=table2.column2;說明:
在where子句中指定連線條件
當被連線的多個表中存在同名欄位時,必須在該欄位前加上"表名"作為字首.
連線的型別
Oracle8i之前的表連線:
等值連線(Equijoin)
非等值連線(Non-Equijoin)
外連線(Outer join):-->左外連線-->右外連線
自連線(Self join)
Oracle9之後新引入的連線形式(支援SQL99規範)
交叉連線(Cross join)
自然連線(Natural join)
使用Using子句建立連線
使用on子句建立連線
外連線(Outer join):-->左外連線-->右外連線-->全外連線
等值連線(Equijoin)
select empno,ename,sal,emp.deptno,dname from emp,dept where emp.deptno = dept.deptno;多表連線中:
- 可使用AND操作符增加查詢條件
- 使用表別名可以簡化查詢
- 使用表名(表別名)字首可提高查詢效率
- 為了連線n個表,至少需要n-1個連線條件
非等值連線(Non-Equijoin)
外連線(Outer join)
使用外連線可以看到參與連線的某一方不滿足連線條件的記錄
外連線運算子為(+)
傳統的外連線分為左外連線和右外連線兩種
語法格式:
select 欄位列表 from table1,table2 where table1.column1(+)=table2.column2; select 欄位列表 from table1,table2 where table1.column1=table2.column2(+); 自連線(Self join) select a.enpno,a.ename,a.ngr,b.ename from emp a,emp bSQL99連線語法
SQL1999規範中規定的連線查詢語法
select 欄位列表 from table1 [cross join table2]|[natural join table2]|[join table2 using(欄位名)]|[join table2 on(table.column_name=table2.column_name)]|[(left | right | full out ) join table2 on(table1.column_name=table2.column_name)];交叉連線(Cross join)
Cross join 產生了一個笛卡爾集,其效果等同於再兩個表進行連線時未使用where子句限定連線條件;
select empno,ename,sal,emp.deptno,dname from emp crossjoin dept;自然連線(Natural join)
Natural join基於兩個表中的全部同名列建立連線
- 從兩個表中選出同名列的值均對應相等的所有行
- 如果兩個表中的同名列的所有資料型別不同,則出錯
- 不允許在參照列上使用表名或者別名作為字首
Using子句
如果不希望參照被連線表的所有同名列進行等值連線,自然連線將無法滿足要求,可以在連線時使用USING子句來設定用於等值連線的列(參照列)名.
select empno,ename,sal,emp.deptno,dname from emp join dept using(deptno);不允許在參照列上使用表名或者別名作為字首
On子句
如果要參照非同名的列進行等值連線,或想設定任意的連線條件,可以使用On子句
select empno,ename,sal,emp.deptno,dname from emp join dept on(emp.deptno=dept.deptno);多表連線
使用SQL99連線語法,兩個以上的表進行連線時應依次/分別指定相臨的兩個表之間的連線條件.
select 欄位列表 from table1 [cross join table2]|[natural join table2]|[join table2 using(欄位名)]|[join table2 on(table.column_name=table2.column_name)]|[(left | right | full out ) join table2 on(table1.column_name=table2.column_name)][cross join table3]|[natural join table3]|[join table3 using(欄位名)]|[join table3 on(table.column_name=table3.column_name)]|[(left | right | full out ) join table3 on(table2.column_name=table3.column_name)]...;內連線和外連線
內連線(Inner join)
在SQL99規範中,內連線只返回滿足連線條件的資料.
外連線(Outer join)
左外連線(Left Outer Join)
兩個表在連線過程中除返回滿足連線條件的行為外,還返回左表中不滿足條件的行為,這種連線稱為左外連線.
右外連線(Right Outer Join)
兩個表在連線過程中除返回滿足連線條件的行為外,還返回右表中不滿足條件的行為,這種連線稱為右外連線.
滿外連線(Full Outer Join)
Oracle9開始新增功能,兩個表在連線過程中除返回滿足連線條件的行為外,還返回兩個表中不滿足條件的所有行為,這種連線稱為滿外連線.
子查詢(Sub Query)
子查詢子查詢在主查詢前執行一次
主查詢使用子查詢的結果
select 欄位列表 fromtablewhere 表示式 operator (select 欄位列表 fromtable);使用子查詢注意事項
- 在查詢時基於未知時應考慮使用子查詢
- 子查詢必須包含在括號內
- 將子查詢放在比較運算子的右側,以增強可讀性.
- 除非進行Top-N分析,否則不要再子查詢中使用Order by子句
- 對單行子查詢使用單行運算子
- 對多行子查詢使用多行運算子
單行子查詢
單行子查詢只返回一行記錄
對單行子查詢可使用單行記錄比較運算子
=--------------等於
>--------------大於
>=------------大於等於
<--------------小於
<=--------------小於等於
<>--------------不等於
select*from emp where sal>(select sal from emp where empno=7000);子查詢空值/多值問題
- 如果子查詢未返回任何行,則主查詢頁不會返回任何結果
- 如果子查詢返回單行結果,則為單行子查詢,可以在主查詢中對其使用相應的單行記錄比較運算子
- 如果子查詢返回多行結果,則為多行子查詢,此時不允許對其使用單行記錄比較運算子
多行子查詢
多行子查詢返回多行記錄
對多行子查詢只能使用多行記錄比較運算子
in--------------等於列表中的任何一個
any--------------和子查詢返回的任意一個值比較
all--------------和子查詢返回的所有值比較
select*from emp where sal>any(selectavg(sal) from emp groupby deptno); select*from emp where sal>all(selectavg(sal) from emp groupby deptno); select*from emp where job in(select job from emp where ename='martin'or ename='ssss');TopN查詢
在oracle中通常採用子查詢的方式來實現Top n查詢
select 欄位列表 from(select 欄位列表 fromtableorderby 排序欄位) where rownum <=n; ------------------------------------------------------------select*from(select*from emp orderby sal desc) where rownum <=5;