<b>Oracle 10g資料庫基礎之基本查詢語句-下-連接配接&子查詢</b>
--資料參考:張烈 張建中《資料庫管理者教育訓練講義》
<b>實驗18:表的連接配接查詢</b>
該實驗的目的是掌握基本的聯合查詢.
<b>表的連接配接</b>
我們要從多張表中要得到資訊,就得以一定的條件将表連接配接在一起查詢。
<a href="http://blog.51cto.com/attachment/201205/192542847.png" target="_blank"></a>
<b>Cartesian</b><b>(笛卡兒)連接配接</b>
當多張表在一起查詢時,沒有給定正确的連接配接條件,結果是第一張表的所有行和第二張表的所有行進行矩陣相乘,得到n*m行的結果集。
一般來說笛卡兒連接配接不是我們需要的結果。
但表如果有一行的情況下,結果有可能正确。
SQL> select ename,dname from emp,dept;
ENAME DNAME
---------- --------------
SMITH ACCOUNTING
ALLEN ACCOUNTING
……..
SMITH RESEARCH
ALLEN RESEARCH
SMITH SALES
ALLEN SALES
SMITH OPERATIONS
ALLEN OPERATIONS
56 rows selected
SQL>
結果為每個員工在每個部門上了一次班,4*14=56,這并不是我們想得到的結果。
要避免笛卡兒連接配接一定要給定一個正确的連接配接條件。
<b>等值連接配接</b>
在連接配接中給定一個相等的連接配接條件。
<b>SQL> select ename,dname from emp,dept where emp.deptno=dept.deptno;</b>
<a href="http://blog.51cto.com/attachment/201205/192605376.png" target="_blank"></a>
<b>當列的名稱在兩張表内重複的時候,要加表的字首來區分,避免不明确的定義。</b>
<b>表的别名</b>
<b>1</b><b>。便于書寫</b>
<b>2</b><b>。将同名的表區分</b>
<b>3</b><b>。一旦定義了别名,表的本名就無效</b>
<b>4</b><b>。隻在該語句内有效</b>
<b>5</b><b>。定義方式為表名後緊跟别名,用空各間隔。</b>
SQL> select ename,dname from emp e,dept d where e.deptno=d.deptno;
<a href="http://blog.51cto.com/attachment/201205/192627831.png" target="_blank"></a>
SQL99的書寫方式
<b>select ename,dname from emp e </b><b>join</b><b> dept d on (e.deptno=d.deptno)</b><b>;</b>
效率是相同的,SQL99是國标
<b>列的别名,為了區分相同的列的名稱,這是别名的本質。</b>
<b>SQL> select ename,dname,e.deptno,d.deptno</b>
<b> from emp e,dept d</b>
<b> where e.deptno=d.deptno;</b>
<a href="http://blog.51cto.com/attachment/201205/192650908.png" target="_blank"></a>
上述顯示有兩個列名稱都叫deptno,我們無法區分。
SQL> select ename,dname,e.deptno "員工表",d.deptno "部門表"
from emp e,dept d
where e.deptno=d.deptno;
<a href="http://blog.51cto.com/attachment/201205/192710249.png" target="_blank"></a>
<b>不等連接配接</b>
連接配接條件不是一個相等的條件。
SQL> select ename,sal,grade
from emp,salgrade
where sal between LOSAL and hisal;
<a href="http://blog.51cto.com/attachment/201205/192729571.png" target="_blank"></a>
<b>外鍵連接配接</b>
将一張表有,而另一張表沒有的行也顯示出來。
SQL> select ename,dname,emp.deptno from emp,dept
where emp.deptno=dept.deptno;
<a href="http://blog.51cto.com/attachment/201205/192746348.png" target="_blank"></a>
這句話不會顯示40号部門,因為40部門沒有員工。
SQL> select ename,dname,dept.deptno from emp,dept where emp.deptno(+)=dept.deptno;
<a href="http://blog.51cto.com/attachment/201205/192808268.png" target="_blank"></a>
<b>+</b><b>号的意思為将沒有員工的部門,用</b><b>NULL</b><b>來比對</b>
<b>+</b><b>号不能同時放在等号的兩邊,隻能出現在一邊。</b>
<b>自連接配接</b>
表的一列和同一個表的另一列作為連接配接的條件。
SQL> select w.ename "下級" ,m.ename "上級"
from emp w,emp m
where w.mgr=m.empno(+);
<a href="http://blog.51cto.com/attachment/201205/192832952.png" target="_blank"></a>
其中“下級”和“上級”為列的别名。區分相同的列。
W和m 為表的别名。區分相同的表。别名的本質。
(+)為了将沒有上級的人也顯示。
<b>過濾結果</b>
想在結果中過濾去一些内容請用and運算。
where w.mgr=m.empno(+)
and w.deptno=30;
<a href="http://blog.51cto.com/attachment/201205/192855190.png" target="_blank"></a>
<b>實驗19:sql99規則的表連接配接操作</b>
該實驗的目的是掌握新的ORACLE表之間的聯合查詢文法.
<b>SQL99</b><b>規則的書寫格式</b>
<b>. Nature(</b><b>自然</b><b>)</b><b>連接配接</b>
這是SQL99規則。
所有同名的列都作為等值條件。
同名的列的資料類型必須比對。
列的名稱前不能加表的字首。
<b>SQL> select ename,deptno,dname from emp natural join dept;</b>
<a href="http://blog.51cto.com/attachment/201205/192912471.png" target="_blank"></a>
Using指定列的連接配接
當有多列同名,但想用其中某一列作為連接配接條件時使用。
<b>SQL> select ename,deptno ,dname from emp join dept using (deptno);</b>
<a href="http://blog.51cto.com/attachment/201205/192930671.png" target="_blank"></a>
SQL99的外鍵連接配接
SQL99寫法
select ename,dname,dept.deptno
from dept left outer join emp
on(dept.deptno=emp.deptno);
9I前的寫法
select ename,dname from emp,dept
where emp.deptno(+)=dept.deptno;
<b>SQL> select ename,dname,dept.deptno</b>
<b> from dept left outer join emp</b>
<b> on(dept.deptno=emp.deptno);</b>
<a href="http://blog.51cto.com/attachment/201205/192958119.png" target="_blank"></a>
<b>知識點</b>
1。笛卡兒連接配接
2。等值連接配接
3。不等連接配接
4。外鍵連接配接
5。自連接配接
6。SQL99的書寫格式
<b>實驗20:子查詢</b>
該實驗的目的是掌握子查詢的文法和概念.
子查詢
誰的工資最多
<a href="http://blog.51cto.com/attachment/201205/193106975.png" target="_blank"></a>
<b>簡單子查詢</b>
1。先于主查詢執行。
2。主查詢調用了子查詢的結果。
3。注意列的個數和類型要比對。
4。子查詢傳回多行要用多行關系運算操作。
5。子查詢要用括号括起來。
SQL> --查詢工資總和高于10号部門工資總和的部門。
SQL> select deptno,sum(sal)
from emp
group by deptno
having sum(sal)>(select sum(sal) from emp where deptno=10);
<a href="http://blog.51cto.com/attachment/201205/193125640.png" target="_blank"></a>
SQL> --查詢每個部門的最大工資是誰。
SQL> select deptno,ename,sal from emp
where (deptno,sal) in
(select deptno,max(sal) from emp group by deptno);
<a href="http://blog.51cto.com/attachment/201205/193147698.png" target="_blank"></a>
子查詢傳回多行,用=不可以,得用in。
子查詢傳回多列,是以對比的列也要比對。
<b>Any </b><b>和</b><b>all</b><b>操作</b>
SQL> select ename,sal from emp where sal<any(1000,2000);
小于2000就可以
<a href="http://blog.51cto.com/attachment/201205/193203371.png" target="_blank"></a>
SQL> select ename,sal from emp where sal<all(1000,2000);
必須小于1000
<a href="http://blog.51cto.com/attachment/201205/193218462.png" target="_blank"></a>
小于all小于最小,大于all大于最大
SQL> select ename,sal,deptno from emp
where sal<all(select avg(sal) from emp group by deptno);
<a href="http://blog.51cto.com/attachment/201205/193235294.png" target="_blank"></a>
小于any小于最大,大于any大于最小
select ename,sal,deptno from emp
where sal>any(select avg(sal) from emp group by deptno)
<a href="http://blog.51cto.com/attachment/201205/193251624.png" target="_blank"></a>
<b>From</b><b>子句中的子查詢</b>
查詢工資大于本部門平均工資的員工。
select ename,e.deptno,sal,asal
from emp e,
(select deptno ,avg(sal) asal from emp group by deptno) a
where e.deptno=a.deptno and sal>asal;
A為視圖,為什麼要使用别名asal,因為表達式不能當列的名稱,别名的本質使用方法是使非法的合法化。
<a href="http://blog.51cto.com/attachment/201205/193314503.png" target="_blank"></a>
<b>互相關聯的子查詢</b>
select ename,sal ,deptno
from emp o
where sal>(select avg(sal) from emp where deptno=o.deptno) ;
<a href="http://blog.51cto.com/attachment/201205/193338541.png" target="_blank"></a>
先運作主查詢,得到第一行,将DEPTNO傳入到子查詢,由子查詢求出AVG(SAL),在判定主查詢的行是否符合查詢的條件。
執行計劃是将子查詢看作視圖的關聯。這叫做SQL的自動改寫。
<b>Exists</b><b>操作</b>
找上司,其中3是常量,你寫什麼都可以。
當子查詢有行時,Exists傳回true
查到行後就不再繼續查詢
當子查詢沒有行時為假,Exists傳回false
select ename,empno,mgr from emp o
where exists(select 3 from emp where mgr=o.empno);
<a href="http://blog.51cto.com/attachment/201205/193357928.png" target="_blank"></a>
<b>《完》</b>
<b>--xjzhujunjie</b>
<b></b>
<b>本文轉自xjzhujunjie 51CTO部落格,原文連結:http://blog.51cto.com/xjzhujunjie/868102</b>