內部合併與外部合併的差異:保留的列、NULL、左外部合併與右外部合併、SQL寫法比較

合併(JOIN)是依ON指定的條件(多半是外鍵與主鍵的值相等),組合兩個資料表的列,產生一個結果資料表的操作。內部合併只把有符合條件之對應列的組合留在結果中,沒有對應列的列,不論來自哪個資料表都會消失。外部合併除了符合的組合之外,即使沒有對應列,也會保留指定一側資料表的列,並以NULL填入另一資料表的欄。保留左側資料表所有列的是左外部合併(LEFT OUTER JOIN),保留右側的是右外部合併(RIGHT OUTER JOIN),兩側都保留的是完全外部合併(FULL OUTER JOIN)。依「是否也要在結果中列出沒有對應列的列」來選擇使用。

項目內部合併(INNER JOIN)外部合併(OUTER JOIN)
結果中保留的列只有符合合併條件的列的組合除了符合的組合,還有指定保留一側資料表中沒有對應列的列
沒有對應列的處理左右兩個資料表的列都會從結果中消失保留一側的列,會把另一資料表的欄設為NULL,作為1列保留。非保留一側的資料表的列會消失
種類1種。可省略INNER,只寫JOIN左外部合併(LEFT)、右外部合併(RIGHT)、完全外部合併(FULL)3種。可省略OUTER
SQL寫法的例子SELECT … FROM 員工 INNER JOIN 部門 ON 員工.部門ID = 部門.部門IDSELECT … FROM 員工 LEFT OUTER JOIN 部門 ON 員工.部門ID = 部門.部門ID
結果列數的例子(4名員工中1人的部門ID為NULL,3個部門中1個沒有員工)3列。部門ID為NULL的員工與沒有員工的部門都不會出現保留員工資料表的左外部合併為4列(部門ID為NULL的員工,部門名稱為NULL)。兩側都保留的完全外部合併為5列
資料表的書寫順序左右對調,結果的列也相同(欄的排列會改變)左外部合併與右外部合併,哪個資料表寫在左側會改變結果。A LEFT OUTER JOIN B與B RIGHT OUTER JOIN A會傳回相同的列
對另一資料表之欄的條件寫在ON或寫在WHERE子句,結果都相同寫在WHERE子句時,以NULL填入的列不符合條件而消失,結果可能與內部合併相同。想保留沒有對應列的列時,要寫在ON
主要用途只想使用兩個資料表都有資料者時(例如為訂單加上顧客姓名)想列出也包含沒有對應列的列時(例如包含尚未設定部門之員工的員工清單),或想找出沒有對應列的列時

數值為具代表性的大致參考值,會因世代或產品而異。

適用於什麼情況

內部合併
只需要兩個資料表都有對應資料的列時使用。例如為訂單清單加上顧客姓名時,若不需要顧客不明的訂單,就用內部合併。
外部合併
想把沒有對應列的列也不遺漏地列出時使用。例如為全體員工清單加上部門名稱,並想保留尚未設定部門的員工時,就用保留員工資料表的左外部合併。進行外部合併後,選出另一資料表主鍵欄為NULL的列,也能找出像從未下單的顧客這類沒有對應列的列。

常見問題

左外部合併與右外部合併有什麼不同?

差別只在保留哪個資料表的所有列。左外部合併即使沒有對應列,也保留在FROM中先寫的左側資料表的列;右外部合併則保留後寫的右側資料表的列。A LEFT OUTER JOIN B與B RIGHT OUTER JOIN A會傳回相同的列,因此為了容易閱讀,常統一以左外部合併撰寫。

為什麼合併的結果會比原本的資料表列數更多?

因為在合併中,符合條件的列的每一種組合都會成為結果的一列。若合併的欄在兩個資料表中都有重複的值,組合的數量就會以相乘的方式增加。例如值為1的列在一方有2列、另一方也有2列,光是這個值就會產生2 × 2 = 4列。

不加合併條件會怎樣?

會成為兩個資料表所有列的組合(笛卡兒積)。這稱為CROSS JOIN,4列的資料表與3列的資料表會得到4 × 3 = 12列。若因忘了寫ON等原因而意外產生笛卡兒積,結果的列數會急遽增加,需要注意。

NULL與NULL在合併條件中會相符嗎?

不會。在SQL中,與NULL的比較不會成為真,因此兩個資料表中合併的欄都是NULL的列也不會被組合。所以在內部合併中,合併的欄為NULL的列會從結果中消失。

理解度檢測

員工表格(員工編號, 姓名, 部門編號)有4筆資料列,部門編號依序為10、20、10、NULL。部門表格(部門編號, 部門名稱)有部門編號為10、20、30的3筆資料列。SELECT 員工.姓名, 部門.部門名稱 FROM 員工 INNER JOIN 部門 ON 員工.部門編號 = 部門.部門編號 的結果有幾筆資料列?

  1. A3筆
  2. B4筆
  3. C12筆
查看答案與解析

正確答案:A. 3筆

INNER JOIN(內部連結)只把滿足ON條件的資料列組合作為結果。部門編號為10的2位員工與部門10的資料列組合,部門編號為20的1位員工與部門20的資料列組合,因此結果為3筆。部門編號為NULL的員工,因為與NULL的比較不會為真,不會與任何部門連結而從結果中消失。沒有員工的部門30也不會出現在結果中。4筆是保留員工表格所有資料列的左外部連結(員工 LEFT OUTER JOIN 部門)時的筆數。12筆是不加條件、產生所有組合的CROSS JOIN(笛卡兒積),即 4 × 3 = 12 筆。

員工表格(員工編號, 姓名, 部門編號)有5筆資料列,部門編號依序為10、20、10、NULL、NULL。部門表格(部門編號, 部門名稱)有部門編號為10、20、30的3筆資料列。SELECT 部門.部門名稱, 員工.姓名 FROM 部門 LEFT OUTER JOIN 員工 ON 部門.部門編號 = 員工.部門編號 的結果有幾筆資料列?

  1. A3筆
  2. B4筆
  3. C5筆
查看答案與解析

正確答案:B. 4筆

LEFT OUTER JOIN(左外部連結)會保留左側表格(此處為部門表格)的所有資料列,若右側表格沒有相符的資料列,就以NULL填入右側欄位,成為一筆資料列。部門10有2位員工而成為2筆,部門20為1筆,沒有員工的部門30成為姓名為NULL的1筆,合計4筆。部門編號為NULL的2位員工不與任何部門相符,而且是不會全部保留的右側表格的資料列,因此不會出現在結果中。若是內部連結,部門30的資料列也會消失而成為3筆。若左右對調成 員工 LEFT OUTER JOIN 部門,5位員工會全部保留而成為5筆。使用外部連結時,確認要保留哪個表格的所有資料列很重要。

表格R的欄位x有值為 1、1、2、3 的4筆資料列,表格S的欄位x有值為 1、1、2、4 的4筆資料列。SELECT * FROM R INNER JOIN S ON R.x = S.x 的結果有幾筆資料列?

  1. A2筆
  2. B3筆
  3. C5筆
查看答案與解析

正確答案:C. 5筆

在連結中,滿足條件的每一種資料列組合都會成為一筆結果。對 x = 1 而言,R的2筆與S的2筆的所有組合都滿足條件,共 2 × 2 = 4 筆;x = 2 則為 1 × 1 = 1 筆。R的3與S的4沒有對應的資料列,不會出現在內部連結的結果中。合計為 4 + 1 = 5 筆。2筆是認為每個相符的值(1與2)只產生一筆時的筆數。3筆是只檢查R的每筆資料列在S中是否有相符的值(如 SELECT * FROM R WHERE x IN (SELECT x FROM S) 這類查詢)時的筆數。若是不加條件的笛卡兒積,則為 4 × 4 = 16 筆。要注意連結欄位的值若有重複,結果的筆數會以相乘的方式增加。

  1. 想從客戶表格(客戶編號, 姓名)與訂單表格(訂單編號, 客戶編號, 金額)中,求出從未下過訂單之客戶的姓名。正確的SQL敘述是下列何者?

前往資料庫基礎的練習題

相關名詞的解說

SQL
在關聯式資料庫中,用來定義表格、搜尋/新增/修改/刪除資料,以及控制權限等的標準語言。由ISO/IEC制定為標準。包括SELECT、INSERT、UPDATE、DELETE、CREATE TABLE、GRANT等敘述。
關聯式資料庫
以由資料列與欄位構成的表格(關聯)表示資料,並以共同的值把表格彼此關聯起來的資料庫。也稱為RDB。以SQL進行查詢與修改,並以主鍵、外鍵等限制維持資料的一致性。
主鍵
用來唯一識別表格中一筆資料列的欄位或欄位組合。具有值不得重複、不得含NULL的限制。從能唯一識別資料列的最小欄位組合(候選鍵)中選出一個作為主鍵。
外鍵
參照其他表格之主鍵(或唯一欄位)的欄位。透過只能存入參照對象中存在的值或NULL的參考完整性限制,防止指向不存在資料列的資料被存入。也可以指定參照對象的資料列被刪除或修改時的動作(拒絕、連帶刪除等)。
正規化
依據欄位之間的函數相依分割關聯式資料庫的表格,讓同一事實不會記錄在多處的設計步驟。可消除資料重複,防止修改異常、插入異常與刪除異常。有第一正規化到第三正規化、BCNF等階段。
檢視表
在關聯式資料庫中,為SELECT敘述命名而定義的虛擬表格。通常本身不保存資料,每次被參照時才從原始表格產生結果。用來簡化複雜的查詢,或限制顯示的欄位與資料列以限制可存取的範圍。

相關的比較