使用外部聯結

已完成

雖然外部聯結並不如內部聯結那麼常見,但在多資料表查詢中使用外部聯結能為您的商務資料提供替代觀點。 和內部聯結相同,您將會表達資料表之間的邏輯關聯性。 不過,您不只會取出具有相同屬性的資料列,也會取出存在於單一或兩個資料表中的所有資料列,無論該資料列在另一個資料表中是否有相符項目。

先前,您已了解如何使用 INNER JOIN 來尋找兩個資料表之間的相符資料列。 如您所見,查詢處理器會透過篩掉不符合在 ON 子句述詞中所表示之條件的資料列,來建置 INNER JOIN 查詢的結果。 結果是系統只會傳回在另一個資料表中具有相符資料列的資料列。 使用 OUTER JOIN 時,您可以選擇顯示在資料表之間具有相符資料列的所有資料列,加上在另一個資料表中沒有相符項目的所有資料列。 讓我們來看一個範例,並探索該程序。

首先,請檢查下列使用 INNER JOIN 撰寫的查詢:

SELECT emp.FirstName, ord.Amount
FROM HR.Employee AS emp
INNER JOIN Sales.SalesOrder AS ord
    ON emp.EmployeeID = ord.EmployeeID;

這些資料列代表 HR.EmployeeSales.SalesOrder 之間的相符項目。 只有那些同時存在於兩個資料表中的 EmployeeID 值才會出現在結果中。

A Venn diagram showing the matching members of the Employee and SalesOrder sets

現在,讓我們檢查下列撰寫為 LEFT OUTER JOIN 的查詢:

SELECT emp.FirstName, ord.Amount
FROM HR.Employee AS emp
LEFT OUTER JOIN Sales.SalesOrder AS ord
    ON emp.EmployeeID = ord.EmployeeID;

此範例使用 LEFT OUTER JOIN 運算子,其會指示查詢處理器保留左側資料表 (HR.Employee) 中的所有資料列,並顯示 Sales.SalesOrder 中相符資料列的 Amount 值。 不過,系統會傳回所有員工,無論該員工是否已承辦銷售訂單。 如果員工沒有相符的銷售訂單,查詢將會傳回 NULL,而不會顯示 Amount 值。

A Venn diagram showing the outer join results of the Employee and SalesOrder sets

OUTER JOIN 語法

外部聯結是透過在 OUTER JOIN 前方使用 LEFT、RIGHT 或 FULL 關鍵字來表示的。 關鍵字的目的是為了指出應該要保留哪一個資料表 (在 JOIN 關鍵字的哪一邊),同時顯示其所有資料列 (無論是否有相符項目)。

使用 LEFT、RIGHT 或 FULL 來定義聯結時,您可以省略 OUTER 關鍵字,如這裡所示:

SELECT emp.FirstName, ord.Amount
FROM HR.Employee AS emp
LEFT JOIN Sales.SalesOrder AS ord
    ON emp.EmployeeID = ord.EmployeeID;

不過,和 INNER 關鍵字相同,撰寫能明確表示所使用之聯結類型的程式碼通常會很有幫助。

使用 OUTER JOIN 撰寫查詢時,請考慮下列指導方針:

  • 如先前所述,請盡量使用資料表別名,不僅是針對 SELECT 清單,ON 子句也一樣。
  • 如同 INNER JOIN,OUTER JOIN 也可以在單一相符資料行或多個相符屬性上執行。
  • 和 INNER JOIN 不同的是,在 FROM 子句中列出及聯結資料表的順序確實會影響到 OUTER JOIN,因為其將決定您針對聯結選擇的是 LEFT 或 RIGHT。
  • 存在 OUTER JOIN 時,多資料表聯結也會更加複雜。 如果將中繼結果繼續與第三個資料表聯結,則中繼結果因 OUTER JOIN 而產生的 NULL 可能會導致問題。 具有 NULL 的資料列可能會被第二個聯結的述詞篩選掉。
  • 若要只顯示不存在任何相符項目的資料列,請在 WHERE 子句中於 OUTER JOIN 述詞之後新增針對 NULL 的測試。
  • FULL OUTER JOIN 很少使用。 其會傳回兩個資料表之間的所有相符資料列,加上來自第一個資料表且在第二個資料表中沒有相符項目的所有資料列,加上來自第二個資料表且在第一個資料表中沒有相符項目的所有資料列。
  • 在沒有 ORDER BY 子句的情況下,將沒有任何方法可以預測傳回之資料列的順序。 沒有辦法知道會先傳回相符的資料列,還是不相符的資料列。