9.3.4? 外連接(OUTER JOIN)
不管是內連接還是帶WHERE子句的多表查詢,都組合自多個表,并生成結果表。換句話說,如果任何一個源表中的行在另一個源表中沒有匹配,DBMS將不把該行放在最后的結果表中。
而外連接告訴ODBC生成的結果表,不僅包含符合連接條件的行,而且還包括左表(左外連接時)、右表(右外連接時)或兩個邊接表(全外連接)中的所有數據行。
SQL的外連接共有3種類型:左外連接,關鍵字為LEFT OUTER JOIN、右外連接,關鍵字為RIGHT OUTER JOIN和全外連接,關鍵字為FULL OUTER JOIN。外連接的用法和內連接一樣,只是將INNER JOIN關鍵字替換為相應的外連接關鍵字即可。
說明?使用外連接時,關鍵字OUTER是可選的,如可用LEFT JOIN替代LEFT OUTER JOIN。
下面分別介紹一下這幾種外連接方式。
1.左外連接
左外連接,LEFT OUTER JOIN,告訴DBMS生成的結果表中,除了包括匹配行外,還包括JOIN關鍵字(FROM子句中)左邊表的不匹配行。左外連接實際上可以表示為:
左外連接 = 內連接 + 左邊表中失配的元組
其中,缺少的右邊表中的屬性值用NULL表示。圖9.17給出了典型的左外連接示意圖。
![]() |
圖9.17? 左外連接 |
實例11? 左連接STUDENT表和COURSE表
左連接STUDENT表和COURSE表,查詢所有同學的學號、姓名、課程代碼、課程名稱、考試時間和成績信息。實例代碼:
SELECT????? ???S.SNO,? SNAME, S.CNO, CNAME, CTEST, MARK |
運行結果如圖9.18所示。
可見,最終得到的結果表中,除了包括兩個表匹配的行(3~20行),還包括了左邊表STUDENT中的不匹配行(1、2行),缺少的右邊表,即COURSE表中的屬性值用NULL表示。
技巧?在SQL Server中,可以在WHERE子句中使用“*=”符號實現左外連接。
![]() |
圖9.18? 左連接STUDENT表和COURSE表的查詢結果 |
在WHERE子句,使用“*=”符號實現左外連接實現上例,代碼如下。
SELECT????? ?S.SNO,? SNAME, S.CNO, CNAME, CTEST, MARK |
運行結果如圖9.19所示。
![]() |
圖9.19? 使用“*=”符號實現的左外連接 |
說明?在Oracle數據庫系統中,只需將“*=”替換成“+=”可以得到相同的結果。
2.右外連接
右外連接(RIGHT OUTER JOIN)告訴DBMS生成的結果表中,除了包括匹配行外,還包括JOIN關鍵字(FROM子句中)右邊表的不匹配行。右外連接實際上可以表示為:
右外連接 = 內連接 + 右邊表中失配的元組 |
其中,缺少的左邊表中的屬性值用NULL表示。圖9.20給出了典型的右外連接示意圖。
![]() |
圖9.20? 右外連接 |
實例12? 右外連接STUDENT表和COURSE表
右外連接STUDENT表和COURSE表,查詢所有同學的學號、姓名、課程代碼、課程名稱、考試時間和成績信息。實例代碼:
SELECT????? ??S.SNO,? SNAME, S.CNO, CNAME, CTEST, MARK |
運行結果如圖9.21所示。
![]() |
圖9.21? 右外連接STUDENT表和COURSE表的查詢結果 |
可見,最終得到的結果表中,除了包括兩個表匹配的行(3~20行),還包括了右邊表COURSE表中的不匹配行(1、2行),缺少的左邊表,即STUDENT表中的屬性值用NULL表示。
技巧?在SQL Server數據庫系統中,可以在WHERE子句中使用“=*”符號實現右外連接。
實例13? 在WHERE子句中使用“=*”符號實現右外連接
在WHERE子句,使用“=*”符號實現實例12,代碼如下。
SELECT????? ??S.SNO,? SNAME, S.CNO, CNAME, CTEST, MARK |
運行結果如圖9.22所示。
![]() |
圖9.22? 使用“=*”符號實現的右外連接 |
3.全外連接
全外連接,FULL OUTER JOIN,告訴DBMS生成的結果表中,除了包括匹配行外,還包括JOIN關鍵字(FROM子句中)左邊表和右邊表的不匹配行。全外連接實際上可以表示為:
全外連接 = 內連接 + 左邊表中失配的元組 + 右邊表中失配的元組。 |
其中,缺少的左邊表或者右邊表中的屬性值用NULL表示。圖9.23給出了典型的全外連接示意圖。
![]() |
圖9.23? 全外連接 |
實例14? 全外連接STUDENT表和COURSE表
全外連接STUDENT表和COURSE表,查詢所有同學的學號、姓名、課程代碼、課程名稱、考試時間和成績信息。實例代碼:
SELECT????? ??S.SNO,? SNAME, S.CNO, CNAME, CTEST, MARK |
運行結果如圖9.24所示。
![]() |
圖9.24? 全外連接STUDENT表和COURSE表的查詢結果 |
可見,最終得到的結果表中,除了包括兩個表匹配的行(5~22行),還包括了右邊表COURSE表中的不匹配行(1、2行),缺少的左邊表,即STUDENT表中的屬性值用NULL表示。以及左邊表,STUDENT表中的不匹配行(3、4行),缺少的右邊表,即COURSE表中的屬性值用NULL表示。