1. 程式人生 > >ORACLE 多表連線與子查詢

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 b
where a.ngr = b.enpno;

 SQL99連線語法

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基於兩個表中的全部同名列建立連線

  • 從兩個表中選出同名列的值均對應相等的所有行
  • 如果兩個表中的同名列的所有資料型別不同,則出錯
  • 不允許在參照列上使用表名或者別名作為字首
select empno,ename,sal,emp.deptno,dname from emp natural join dept;

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;