SQL中的left outer join,inner join,right outer join用法詳解


LEFT JOIN 關鍵字會從左表 (table_name1) 那里返回所有的行,即使在右表 (table_name2) 中沒有匹配的行。
LEFT JOIN 關鍵字語法
SELECT column_name(s) FROM table_name1 LEFT JOIN table_name2 ON table_name1.column_name=table_name2.column_name 注釋:在某些數據庫中, LEFT JOIN 稱為 LEFT OUTER JOIN。

原始的表

"Persons" 表:
Id_P
LastName
FirstName
Address
City
1
Adams
John
Oxford Street
London
2
Bush
George
Fifth Avenue
New York
3
Carter
Thomas
Changan Street
Beijing
"Orders" 表:
Id_O
OrderNo
Id_P
1
77895
3
2
44678
3
3
22456
1
4
24562
1
5
34764
65

 

現在,我們希望列出所有的人,以及他們的定購 - 如果有的話。
您可以使用下面的 SELECT 語句:
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo FROM Persons LEFT JOIN Orders ON Persons.id_P=Orders.id_P ORDER BY Persons.LastName  結果集
LastName
FirstName
OrderNo
Adams
John
22456
Adams
John
24562
Carter
Thomas
77895
Carter
Thomas
44678
Bush
George

  
LEFT JOIN 關鍵字會從左表 (Persons) 那里返回所有的行,即使在右表 (Orders) 中沒有匹配的行。

 這兩天,在研究SQL語法中的inner join多表查詢語法的用法,通過學習,發現一個SQL命令,竟然涉及到很多線性代數方面的知識,現將這些知識系統地記錄如下:

      使用關系代數合並數據
1 關系代數
合並數據集合的理論基礎是關系代數,它是由E.F.Codd於1970年提出的。
在關系代數的形式化語言中:
?          用表、或者數據集合表示關系或者實體。
?          用行表示元組。
?          用列表示屬性。
關系代數包含以下8個關系運算符
?          選取――返回滿足指定條件的行。
?          投影――從數據集合中返回指定的列。
?          笛卡爾積――是關系的乘法,它將分別來自兩個數據集合中的行以所有可能的方式進行組合。
?          並――關系的加法和減法,它可以在行的方向上合並兩個表中的數據,就像把一個表壘在另一個表之上一樣。
?          交――返回兩個數據集合所共有的行。
?          差――返回只屬於一個數據集合的行。
?          連接――在水平方向上合並兩個表,其方法是:將兩個表中在共同數據項上相互匹配的那些行合並起來。
?          除――返回兩個數據集之間的精確匹配。
此外,作為一種實現現代關系代數運算的方法,SQL還提供了:
?          子查詢――類似於連接,但更靈活;在外部查詢中,方式可以使用表達式、列表或者數據集合的地方都可以使用子查詢的結果。
本章將主要講述多種類型的連接、簡單的和相關的子查詢、幾種類型的並、關系除以及其他的內容。
2 使用連接
2.1 連接類型
在關系代數中,連接運算是由一個笛卡爾積運算和一個選取運算構成的。首先用笛卡爾積完成對兩個數據集合的乘運算,然后對生成的結果集合進行選取運算,確保只把分別來自兩個數據集合並且具有重疊部分的行合並在一起。連接的全部意義在於在水平方向上合並兩個數據集合(通常是表),並產生一個新的結果集合,其方法是將一個數據源中的行於另一個數據源中和它匹配的行組合成一個新元組。
SQL提供了多種類型的連接方式,它們之間的區別在於:從相互交疊的不同數據集合中選擇用於連接的行時所采用的方法不同。
連接類型          定義
內連接          只連接匹配的行
左外連接          包含左邊表的全部行(不管右邊的表中是否存在與它們匹配的行),以及右邊表中全部匹配的行
右外連接          包含右邊表的全部行(不管左邊的表中是否存在與它們匹配的行),以及左邊表中全部匹配的行
全外連接          包含左、右兩個表的全部行,不管另外一邊的表中是否存在與它們匹配的行。
(H)(theta)連接          使用等值以外的條件來匹配左、右兩個表中的行
交叉連接          生成笛卡爾積-它不使用任何匹配或者選取條件,而是直接將一個數據源中的每個行與另一個數據源的每個行都一一匹配
在INFORMIX中連接表的查詢
如果FROM子句指定了多於一個表引用,則查詢會連接來自多個表的行。連接條件指定各列之間(每個表至少一列)進行連接的關系。因為正在比較連接條件中的列,所以它們必須具有一致的數據類型。
SELECT語句的FROM子句可以指定以下幾種類型的連接
FROM子句關鍵字          相應的結果集
CROSS JOIN          笛卡爾乘積(所有可能的行對)
INNER JOIN          僅對滿足連接條件的CROSS中的列
LEFT OUTER JOIN          一個表滿足條件的行,和另一個表的所有行
RIGHT OUTER JOIN          與LEFT相同,但兩個表的角色互換
FULL OUTER JOIN        LEFT OUTER 和 RIGHT OUTER中所有行的超集

2.2 內連接(Inner Join
內連接是最常見的一種連接,它頁被稱為普通連接,而E.FCodd最早稱之為自然連接。
下面是ANSI SQL-92標准
select * 
from    t_institution i 
inner join t_teller t 
on i.inst_no = t.inst_no
where i.inst_no = "5801"
其中inner可以省略。
等價於早期的連接語法
select * 
from t_institution i, t_teller t 
where i.inst_no = t.inst_no
and i.inst_no = "5801"

2.3 外連接
2.3.1          左外連接(Left Outer Jion)
select * 
from    t_institution i 
left outer join t_teller t 
on i.inst_no = t.inst_no
其中outer可以省略。
2.3.2          右外連接(Rigt Outer Jion)
select * 
from    t_institution i 
right outer join t_teller t 
on i.inst_no = t.inst_no
2.3.3          全外連接(Full Outer)
全外連接返回參與連接的兩個數據集合中的全部數據,無論它們是否具有與之相匹配的行。在功能上,它等價於對這兩個數據集合分別進行左外連接和右外連接,然后再使用消去重復行的並操作將上述兩個結果集合並為一個結果集。
在現實生活中,參照完整性約束可以減少對於全外連接的使用,一般情況下左外連接就足夠了。在數據庫中沒有利用清晰、規范的約束來防范錯誤數據情況下,全外連接就變得非常有用了,你可以使用它來清理數據庫中的數據。
select * 
from    t_institution i 
full outer join t_teller t 
on i.inst_no = t.inst_no
2.3.4          外連接與條件配合使用
當在內連接查詢中加入條件是,無論是將它加入到join子句,還是加入到where子句,其效果是完全一樣的,但對於外連接情況就不同了。當把條件加入到join子句時,SQL Server、Informix會返回外連接表的全部行,然后使用指定的條件返回第二個表的行。如果將條件放到where子句中,SQL Server將會首先進行連接操作,然后使用where子句對連接后的行進行篩選。下面的兩個查詢展示了條件放置位子對執行結果的影響:
條件在join子句
select * 
from    t_institution i 
left outer join t_teller t 
on i.inst_no = t.inst_no
and i.inst_no = “5801”
結果是:
inst_no      inst_name              inst_no      teller_no    teller_name
5801         天河區                 5801         0001         tom
5801         天河區                 5801         0002         david
5802         越秀區
5803         白雲區
條件在where子句
select * 
from    t_institution i 
left outer join t_teller t 
on i.inst_no = t.inst_no
where i.inst_no = “5801”
結果是:
inst_no      inst_name              inst_no      teller_no    teller_name
5801         天河區                 5801         0001         tom
5801         天河區                 5801         0002         david

2.4 自身連接
自身連接是指同一個表自己與自己進行連接。這種一元連接通常用於從自反關系(也稱作遞歸關系)中抽取數據。例如人力資源數據庫中雇員與老板的關系。
下面例子是在機構表中查找本機構和上級機構的信息。
select s.inst_no superior_inst, s.inst_name sup_inst_name, i.inst_no, i.inst_name
from t_institution i
join t_institution s
on i.superior_inst = s.inst_no

結果是:
superior_inst sup_inst_name          inst_no      inst_name
800             廣州市                 5801         天河區
800             廣州市                 5802         越秀區
800             廣州市                 5803         白雲區

2.5 交叉(無限制) 連接
交叉連接用於對兩個源表進行純關系代數的乘運算。它不使用連接條件來限制結果集合,而是將分別來自兩個數據源中的行以所有可能的方式進行組合。數據集合中一的每個行都要與數據集合二中的每一個行分別組成一個新的行。例如,如果第一個數據源中有5個行,而第二個數據源中有4個行,那么在它們之間進行交叉連接就會產生20個行。人們將這種類型的結果集稱為笛卡爾乘積。
大多數交叉連接都是由於錯誤操作而造成的;但是它們卻非常適合向數據庫中填充例子數據,或者預先創建一些空行以便為程序執行期間所要填充的數據保留空間。
select *
from    t_institution i 
cross join t_teller t
在交叉連接中沒有on條件子句
      通過以上知識,還真是系統地學習了一番,發現inner join其實可以通過最初的多表查詢方式來實現,例如:

select * from    t_institution i ,t_teller t where i.inst_no = t.inst_no and i.inst_no = "5801"

其實,inner join就是對多表查詢的一種解決方案而已。而外連接,還是有其特定的用處的,實際上就相當於一個開區間,而內連接就是一個閉區間。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM