SQL Server之連線
轉載自:http://www.cnblogs.com/jiajiayuan/archive/2012/01/16/2321385.html
在sql server中,我們經常能用到連線。
連線的分類:
- 交叉連線CROSS JOIN
- 內連線INNER JOIN
- 外連線{左外連線LEFT [OUTER] JOIN ;右外連線RIGHT [OUTER] JOIN;全外連線full [outer] join}
- 自連線
以下通過例子來了解各個連線的異同點:
有兩張表Teacher表和Course表:
交叉連線:
1.如果不帶WHERE條件子句,它將會返回被連線的兩個表的笛卡爾積,返回結果的行數等於兩個錶行數的乘積;
select * from Course cross join Teacher
結果為:
由此結果可知,它的結果與 SELECT * FROM Course,Teacher 的結果相同。
2.如果有WHERE子句的話,往往會先生成兩個表行數乘積的資料表然後才根據WHERE條件從中選擇。
1. select * from Course,Teacher where Course.T#=Teacher.T#
2. select * from Course cross join Teacher where Course.T#=Teacher.T# (注:cross join後加條件只能用where,不能用on)
3. select * from Course inner join Teacher on Course.T#=Teacher.T#
結果為:
一般情況下,在效率上,Where可能具有和Inner join一樣的效率,但是,在多表連線時,我們並不推薦使用where語句。
所以如果可以選擇,我們最好使用語句3,有時使用Join語句可以幫助檢查語句中的無效或者誤寫的關聯條件。
內連線
內連線表示兩邊表同時符合條件的組合,就相當於普通的CROSS JOIN,只是格式不一樣,
INNER JOIN在後面有一個ON子句(相當於WHERE)的搜尋條件,用於過濾返回的行。
內連線沒有笛卡爾積那麼複雜要先生成行數乘積的資料表,所以內連線的效率要高於笛卡爾積的交叉連線。
外連線
指定條件的內連線,僅僅返回符合連線條件的條目。
外連線則不同,返回的結果不僅包含符合連線條件的行,而且包括左表(左外連線時), 右表(右連線時)或者兩邊連線(全外連線時)的所有資料行。
1)左外連線LEFT
[OUTER] JOIN
顯示符合條件的資料行,同時顯示左邊資料表不符合條件的資料行,右邊沒有對應的條目顯示NULL。
select * from Course left outer join Teacher on Course.T#=Teacher.T#
結果為:
2)右外連線RIGHT
[OUTER] JOIN
顯示符合條件的資料行,同時顯示右邊資料表不符合條件的資料行,左邊沒有對應的條目顯示NULL。
select * from Course right outer join Teacher on Course.T#=Teacher.T#
結果為:
3)全外連線full [outer] join
顯示符合條件的資料行,同時顯示左右不符合條件的資料行,相應的左右兩邊顯示NULL,即顯示左連線、右連線和內連線的並集。
select * from Course full outer join Teacher on Course.T#=Teacher.T#
結果為:
自連線
其實,在Sql Server中,我們還經常用到一種連線——自連線。
通過以下的例子,來了解自連線:
表樹形結構表tb_TestTreeView
解決問題: 樹形層次結構顯示
/*
這是一個地區表,裡面存放了地區名及其所屬上級地區,假設現在需要查詢出各地區及其所屬上級地區。
*/
自連線的方法1:
select [Name] as '地區名',
(select [Name] from tb_TestTreeView as a
where a.ID = b.Parent ) as '上級地區名'
from tb_TestTreeView as b
自連線的方法2:
select a.[Name] as '地區名',
b.[Name] as '上級地區名'
from tb_TestTreeView as a
left join tb_TestTreeView as b
on a.Parent = b.ID
結果為:
自連線三級(左聯接):
select a.[Name] as '地區名',
b.[Name] as '上級地區名',
c.[Name] as '上上級地區名'
from tb_TestTreeView as a
left join tb_TestTreeView as b
on a.Parent = b.ID
left join tb_TestTreeView as c
on b.parent=c.id
結果為:
自連線三級(內聯接):
select a.[Name] as '地區名',
b.[Name] as '上級地區名',
c.[Name] as '上上級地區名'
from tb_TestTreeView as a
inner join tb_TestTreeView as b
on a.Parent = b.ID
inner join tb_TestTreeView as c
on b.parent=c.id
結果為:
自連線四級(左連結):
select a.[Name] as '地區名',
b.[Name] as '上級地區名',
c.[Name] as '上上級地區名',
d.[Name] as '上上上級地區名'
from tb_TestTreeView as a
left join tb_TestTreeView as b
on a.Parent = b.ID
left join tb_TestTreeView as c
on b.parent=c.id
left join tb_TestTreeView as d
on c.parent=d.id
結果為:
自連線四級(內連結):
select a.[Name] as '地區名',
b.[Name] as '上級地區名',
c.[Name] as '上上級地區名',
d.[Name] as '上上上級地區名'
from tb_TestTreeView as a
inner join tb_TestTreeView as b
on a.Parent = b.ID
inner join tb_TestTreeView as c
on b.Parent = c.ID
inner join tb_TestTreeView as d
on c.Parent = d.ID
結果為: