前言
現實中有這么一種需求,有時候我們需要查詢的數據是在多個表中的,那么如何從多個表中查詢數據
呢?這就需要通過表的連接來實現查詢了。
笛卡爾積
在定義連接之前我們需要簡單的了解一下笛卡爾積,筆者不會糾結與其定義,只是看看其實際效果
其實笛卡爾積就是沒有連接條件或者連接條件無效的連接,例如:
[sql] view plaincopyprint?
select *from emp ,dept;--其結果傾向于一個巨大的記錄數,無實際意義
select *from emp ,dept;--其結果傾向于一個巨大的記錄數,無實際意義
上面可以看出笛卡爾積得出的是一個巨大的無意義的記錄集合,我們可以通過在where子句中使用
有效的連接來避免這種情況,使之具有實際意義。
連接定義
就是在笛卡爾積的基礎上使用連接條件,例如根據兩個表的相同列進行連接。若果要進行n個表的
連接那么就的添加n-1個連接條件。例如:
[sql] view plaincopyprint?
select *from emp ,dept where emp.deptno = dept.deptno;
select *from emp ,dept where emp.deptno = dept.deptno;
連接類型
連接主要有兩種類型等值連接、非等值連接.
還包括一些其他的連接方式:多連接、自連接、 定置運算符
等值連接
上面已經使用過了,即是表連接的where條件是一個表的列等于另一個表的列,通常情況下是主鍵和
外鍵的判等連接。
[sql] view plaincopyprint?
select *from emp ,dept where emp.deptno = dept.deptno;
select *from emp ,dept where emp.deptno = dept.deptno;
Tips:因為deptno在兩個表中都存在,所以要使用表.字段的形式,否則oracle認為其歧義
等值連接中同樣還可以添加約束條件
[sql] view plaincopyprint?
select *from emp ,dept where emp.deptno = dept.deptno and emp.ename ='CLARK';
--結果只取一條記錄
select *from emp ,dept where emp.deptno = dept.deptno and emp.ename ='CLARK';
--結果只取一條記錄
同樣可以定義標的別名,不過需要注意的是定義了別名之后,必須通過別名訪問字段,不能通過
表明來訪問了
[sql] view plaincopyprint?
select *from emp e ,dept d where e.deptno = d.deptno and e.ename ='CLARK';
select *from emp e ,dept d where e.deptno = d.deptno and e.ename ='CLARK';
非等值連接
通過觀察scott用戶下的emp表和salgrade表,可以知道的是他們之間沒有直接的對應項,而是
emp的sal列的值在salgrade表中的LOSAL和HISAL之間,他們不是等值連接。
[sql] view plaincopyprint?
select * from emp e,salgrade s where e.sal between s.losal and s.hisal;
select * from emp e,salgrade s where e.sal between s.losal and s.hisal;
外連接
使用外連接,返回連接兩邊有一邊為NULL的記錄,外連接的運算符是(+)
外連接運算符可以在左邊也可以在右邊,但是不能同時在左邊和右邊,
有(+)的一邊表示這邊的值要么等于另一邊,要么為NULL
例子:
[sql] view plaincopyprint?
select *from emp e ,dept d where e.deptno(+) = d.deptno ;
--表明e.deptno可以為NULL
select *from emp e ,dept d where e.deptno(+) = d.deptno ;
--表明e.deptno可以為NULL
同理,右邊的情況是一樣的,這里就不演示了
右外連接
以連接右邊的表為基準對齊,不足內容補位空值
[sql] view plaincopyprint?
select *from emp e right outer join dept d on(e.deptno =d.deptno);
select *from emp e right outer join dept d on(e.deptno =d.deptno);
這種方式的產生的結果與下面的結果一樣
[sql] view plaincopyprint?
select *from emp e ,dept d where e.deptno(+) = d.deptno ;
select *from emp e ,dept d where e.deptno(+) = d.deptno ;
左外連接
以連接左邊的表為基準對齊,不足內容補位空值
[sql] view plaincopyprint?
select *from emp e left outer join dept d on(e.deptno =d.deptno);
select *from emp e,dept d where e.deptno = d.deptno(+);
select *from emp e left outer join dept d on(e.deptno =d.deptno);
select *from emp e,dept d where e.deptno = d.deptno(+);
可以看出哪邊補位,(+)就在哪邊!
全外連接
通俗的講:左邊,右邊都可以出現NULL(但是不可能同時出現)
雖然(+)不能同時添加到兩邊,但是從9i之后可以使用下面的方式進行
[sql] view plaincopyprint?
select *from emp e full outer join dept d on(e.deptno =d.deptno);
select *from emp e full outer join dept d on(e.deptno =d.deptno);
這種方式查出來的記錄相較于前面的一般會多一些
原文轉自:http://blog.csdn.net/kiritor/article/details/8771280