outer - sql right join




“INNER JOIN”和“OUTER JOIN”有什麼區別? (20)

LEFT JOINRIGHT JOINFULL JOIN適應?


“INNER JOIN”和“OUTER JOIN”有什麼區別?

它們是SQL中最常用的存在運算符,INNER JOIN用於“存在”並LEFT OUTER JOIN用於“不存在”。

考慮這些查詢:

users who have posted and have votes
users who have posted but have no badges

尋找基於集合的解決方案(行業術語)的人會將相應的查詢識別為:

users who have posted INTERSECT users who have votes
users who have posted MINUS users who have badges

將它們轉換為標準SQL:

SELECT UserId FROM Posts
INTERSECT 
SELECT UserId FROM Votes;

SELECT UserId FROM Posts
EXCEPT 
SELECT UserId FROM Badges;

其他人會考慮類似的集合包含:

users who have posted and IN the set of users who have votes
users who have posted and NOT IN the set of users who have badges

將它們轉換為標準SQL:

SELECT UserId 
  FROM Posts
 WHERE UserId IN ( SELECT UserId FROM Votes );

SELECT UserId 
  FROM Posts
 WHERE UserId NOT IN ( SELECT UserId FROM Badges );

有些人會考慮集合中的“存在”,例如

users who have posted and EXIST in the set of users who have votes
users who have posted and do NOT EXIST in the set of users who have badges

這些翻譯成標準的SQL(注意,我們現在需要使用,即變量範圍pvb):

SELECT p.UserId 
  FROM Posts p
 WHERE EXISTS ( SELECT *
                  FROM Votes v
                 WHERE v.UserId = p.UserId );

SELECT p.UserId 
  FROM Posts p
 WHERE NOT EXISTS ( SELECT *
                      FROM Badges b
                     WHERE b.UserId = p.UserId );

但是,我發現“行業標準”方法是專門使用連接。我不知道這裡的想法是什麼(儀器法則過早優化?),所以我將直接進入語法:

SELECT p.UserId 
  FROM Posts p
       INNER JOIN Votes v ON v.UserId = p.UserId;

SELECT p.UserId 
  FROM Posts p
       LEFT JOIN Badges b ON b.UserId = p.UserId
 WHERE b.UserId IS NULL;

注意事項:

  • 唯一的投影距離Users,但我們仍然需要所有這些範圍變量(pvb)為搜索條件。
  • UserId IS NULL搜索條件“屬於”的了OUTER JOIN,但在查詢中斷開。
  • LEFT是行業標準:專業人士將重寫查詢以避免使用RIGHT
  • OUTER從關鍵字LEFT OUTER JOIN被省略。

閉幕致辭:

有時,連接僅用於查詢,以確定值是否存在或不存在於另一個集合中。學會仔細查看正在投影的屬性(SELECT子句中的列):如果連接表中沒有,那麼它們只是用作存在操作符。另外,對於外連接,查找實例<key_column> IS NULLWHERE的條款。


內部聯接

僅檢索匹配的行,即A intersect B

SELECT *
FROM dbo.Students S
INNER JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

左外連接

選擇第一個表中的所有記錄,以及第二個表中與連接鍵匹配的所有記錄。

SELECT *
FROM dbo.Students S
LEFT JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

完全外部加入

選擇第二個表中的所有記錄,以及第一個表中與連接鍵匹配的所有記錄。

SELECT *
FROM dbo.Students S
FULL JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

參考



INNER JOIN要求在比較兩個表時至少存在匹配。例如,表A和表B表示A 8 B(A交點B)。

LEFT OUTER JOIN並且LEFT JOIN是一樣的。它給出了兩個表中匹配的所有記錄以及左表的所有可能性。

同樣,RIGHT OUTER JOINRIGHT JOIN是相同的。它給出了兩個表中匹配的所有記錄以及右表的所有可能性。

FULL JOIN是複制LEFT OUTER JOINRIGHT OUTER JOIN不復制的組合。


內部聯接內部聯接關注於兩個表之間的共性。使用內部聯接時,要比較的兩個(或多個)表之間必須至少存在一些匹配數據。內部聯接搜索表以匹配或重疊數據。找到它後,內部聯接將信息組合併返回到一個新表中。

外部聯接外部聯接返回一組記錄(或行),這些記錄包括內部聯接將返回的內容,但還包括在其他表中未找到對應匹配的其他行。

外連接有三種類型:

左外連接(或左連接)右外連接(或右連接)完全外連接(或完全連接)這些外連接中的每一個都指的是正在進行比較,組合和返回的數據部分。有時在此過程中會產生空值,因為某些數據是共享的,而其他數據則不是。


內部聯接。

連接組合了兩個表中的行。一個內連接嘗試根據您在查詢中指定的標準,這兩個表匹配,並且只返回匹配的行。如果連接中第一個表中的行與第二個表中的兩個行匹配,則結果中將返回兩行。如果第一個表中的某行與第二個表中的行不匹配,則不會返回該行; 同樣,如果第二個表中的某行與第一個表中的行不匹配,則不會返回。

外加入。

一個左連接試圖找到第二個表匹配第一個表中的行的行。如果找不到匹配項,它將返回第一個表中的列,並將第二個表中的列留空(null)。


連接用於組合來自兩個表的數據,結果是一個新的臨時表。 連接基於謂詞謂詞執行,謂詞用於執行連接。 內連接和外連接之間的區別在於內連接將僅返回基於連接謂詞實際匹配的行。 讓我們考慮員工和位置表:

內部聯接: - 內部聯接通過基於聯接謂詞組合兩個表( EmployeeLocation )的列值來創建新的結果表。 該查詢將Employee的每一行與Location的每一行進行比較,以查找滿足join-predicate的所有行對。 當通過匹配非NULL值來滿足連接謂詞時, EmployeeLocation的每對匹配行的列值將合併到結果行中。 以下是內連接的SQL的外觀:

select  * from employee inner join location on employee.empID = location.empID
OR
select  * from employee, location where employee.empID = location.empID

現在,這是運行SQL的結果如下:

外連接: -外連接不要求兩個連接表中的每個記錄都有匹配的記錄。 即使沒有其他匹配記錄,聯接表也會保留每條記錄。 外連接進一步細分為左外連接和右外連接,具體取決於保留哪個表的行(左或右)。

左外連接: -表的左外連接(或簡稱左連接)的結果EmployeeLocation始終包含“左”表( Employee )的所有記錄,即使連接條件未找到任何匹配的記錄“右”表( 位置 )。 以下是使用上表的左外連接的SQL的樣子:

select  * from employee left outer join location on employee.empID = location.empID;
//Use of outer keyword is optional

現在,運行此SQL的結果如下:

右外連接: -右外連接(或右連接)非常類似於左外連接,除非對錶的處理反轉。 “右”表( 位置 )中的每一行將至少出現在連接表中一次。 如果“左”表( Employee )中沒有匹配的行,則Employee中的列將顯示NULL,以表示Location中沒有匹配的記錄。 這就是SQL的樣子:

select * from employee right outer join location  on employee.empID = location.empID;
//Use of outer keyword is optional

使用上面的表格,我們可以顯示右外連接的結果集是什麼樣的:

完全外部聯接: -完全外部聯接或完全聯接是通過在聯接的結果中包含不匹配的行來保留不匹配的信息,使用完全外部聯接 。 它包括來自兩個表的所有行,無論另一個表是否具有匹配值。

圖像來源

MySQL 8.0參考手冊 - 連接語法

Oracle Join操作


以下內容摘自格雷厄姆·埃利斯(Graham Ellis)在博客“馬口”(Horse's Mouth)上發表的文章“ MySQL - LEFT JOIN和RIGHT JOIN,INNER JOIN AND OUTER JOIN ”。

在諸如MySQL之類的數據庫中,數據被分成許多表,然後通過JOINSELECT命令中將它們連接(連接)在一起以從多個表中讀取記錄。 閱讀此示例以了解其工作原理。

首先,一些樣本數據:

people
    mysql> select * from people;
    +------------+--------------+------+
    | name       | phone        | pid  |
    +------------+--------------+------+
    | Mr Brown   | 01225 708225 |    1 |
    | Miss Smith | 01225 899360 |    2 |
    | Mr Pullen  | 01380 724040 |    3 |
    +------------+--------------+------+
    3 rows in set (0.00 sec)

property
    mysql> select * from property;
    +------+------+----------------------+
    | pid  | spid | selling              |
    +------+------+----------------------+
    |    1 |    1 | Old House Farm       |
    |    3 |    2 | The Willows          |
    |    3 |    3 | Tall Trees           |
    |    3 |    4 | The Melksham Florist |
    |    4 |    5 | Dun Roamin           |
    +------+------+----------------------+
    5 rows in set (0.00 sec)

定期加入

如果我們進行常規JOIN(沒有關鍵字INNER,OUTER,LEFT或RIGHT),那麼我們將獲得在兩個表中以適當方式匹配的所有記錄,並且不報告兩個不匹配的傳入表中的記錄:

mysql> select name, phone, selling 
from people join property 
on people.pid = property.pid;
+-----------+--------------+----------------------+
| name      | phone        | selling              |
+-----------+--------------+----------------------+
| Mr Brown  | 01225 708225 | Old House Farm       |
| Mr Pullen | 01380 724040 | The Willows          |
| Mr Pullen | 01380 724040 | Tall Trees           |
| Mr Pullen | 01380 724040 | The Melksham Florist |
+-----------+--------------+----------------------+
4 rows in set (0.01 sec)

LEFT JOIN

如果我們進行LEFT JOIN,我們會以相同的方式獲得匹配的所有記錄,並且在IN ADDITION中我們為連接的左表中的每個不匹配的記錄獲得額外的記錄 - 從而確保(在此示例中)每個PERSON都被提及:

   mysql> select name, phone, selling 
    from people left join property 
    on people.pid = property.pid; 
    +------------+--------------+----------------------+
    | name       | phone        | selling              |
    +------------+--------------+----------------------+
    | Mr Brown   | 01225 708225 | Old House Farm       |
    | Miss Smith | 01225 899360 | NULL <<-- unmatch    |
    | Mr Pullen  | 01380 724040 | The Willows          |
    | Mr Pullen  | 01380 724040 | Tall Trees           |
    | Mr Pullen  | 01380 724040 | The Melksham Florist |
    +------------+--------------+----------------------+
    5 rows in set (0.00 sec)

正確的加入

如果我們進行RIGHT JOIN,我們會獲得匹配的所有記錄和IN ADDITION為連接右表中每個不匹配記錄的額外記錄 - 在我的示例中,這意味著即使我們不這樣做,每個屬性也會被提及有賣家詳情:

mysql> select name, phone, selling 
from people right join property 
on people.pid = property.pid;
+-----------+--------------+----------------------+
| name      | phone        | selling              |
+-----------+--------------+----------------------+
| Mr Brown  | 01225 708225 | Old House Farm       |
| Mr Pullen | 01380 724040 | The Willows          |
| Mr Pullen | 01380 724040 | Tall Trees           |
| Mr Pullen | 01380 724040 | The Melksham Florist |
| NULL      | NULL         | Dun Roamin           |
+-----------+--------------+----------------------+
5 rows in set (0.00 sec)

INNER JOIN執行完全連接,就像第一個示例一樣,在最後兩個示例中,可以在LEFT或RIGHT之後添加單詞OUTER - 它提供了ODBC兼容性,並且不添加額外的功能。


內連接和外連接之間的區別如下:

  1. 內連接是基於匹配元組組合表的連接,而外連接是基於匹配和不匹配元組組合表的連接。
  2. 內連接合併來自兩個表的匹配行,其中省略了不匹配的行,而外連接合併來自兩個表的行,不匹配的行填充空值。
  3. 內連接就像一個交叉操作,而外連接就像一個聯合操作。
  4. 內連接是兩種類型,而外連接是三種類型。
  5. 內連接較慢,而外連接比內連接快。

內部聯接要求聯接表中存在具有相關ID的記錄。

即使右側沒有任何內容,外連接也將返回左側的記錄。

例如,您有一個Orders和一個OrderDetails表。 它們與“OrderID”相關聯。

命令

  • 訂單ID
  • 顧客姓名

訂單詳細信息

  • OrderDetailID
  • 訂單ID
  • 產品名稱
  • 數量
  • 價錢

請求

SELECT Orders.OrderID, Orders.CustomerName
  FROM Orders 
 INNER JOIN OrderDetails
    ON Orders.OrderID = OrderDetails.OrderID

將僅返回OrderDetails表中也包含某些內容的訂單。

如果將其更改為OUTER LEFT JOIN

SELECT Orders.OrderID, Orders.CustomerName
  FROM Orders 
  LEFT JOIN OrderDetails
    ON Orders.OrderID = OrderDetails.OrderID

然後它將返回Orders表中的記錄,即使它們沒有OrderDetails記錄。

您可以使用此命令通過添加WHERE OrderDetails.OrderID IS NULLWHERE OrderDetails.OrderID IS NULL子句來查找沒有任何指示可能的孤立訂單的OrderDetails的訂單。


在批評了備受喜愛的紅色陰影維恩圖之後,我認為發布自己的嘗試是公平的。

雖然@Martin Smith的答案在很長一段時間內是最好的,但他只顯示每個表中的鍵列,而我認為理想情況下也應該顯示非鍵列。

在半小時內我能做的最好的事情,我仍然認為它沒有充分顯示由於缺少鍵值TableB或者OUTER JOIN實際上是聯合而不是連接而存在空值:


如果在連接的另一側(右側)存在匹配記錄,則內部聯接僅顯示行。

(左)外連接顯示左側每條記錄的行,即使連接的另一側(右側)沒有匹配的行。 如果沒有匹配的行,則另一側(右側)的列將顯示NULL。


如果沒有共同記錄,則表的不同之處在於表的連接方式。

  • JOININNER JOIN僅表示兩個表共有的記錄相同。記錄是否通用由join子句中的字段決定。例如:

    FROM t1
    JOIN t2 on t1.ID = t2.ID
    

    表示僅顯示ID兩個表中存在相同值的記錄。

  • LEFT JOINLEFT OUTER JOIN左表中的所有記錄(即SQL語句之前的記錄)相同並且意味著顯示右表中匹配記錄的存在。

  • RIGHT JOIN與...相同RIGHT OUTER JOIN且意味著相反LEFT JOIN,即顯示來自第二(右)表的所有記錄,並且僅顯示來自第一(左)表的記錄。

來源:LEFT,RIGHT,INNER,OUTER,JOIN之間有什麼區別?



答案是每個人的意思,所以在結果中。

注意 :
SQLite沒有RIGHT OUTER JOINFULL OUTER JOIN
並且也MySQL沒有FULL OUTER JOIN

我的回答是基於以上註釋

如果有兩個這樣的表:

--[table1]               --[table2]
id | name                id | name
---+-------              ---+-------
1  | a1                  1  | a2
2  | b1                  3  | b2

CROSS JOIN / OUTER JOIN:
您可以將所有這些表數據與CROSS JOIN以下內容一起使用,

SELECT * FROM table1, table2
--[OR]
SELECT * FROM table1 CROSS JOIN table2

--[Results:]
id | name | id | name 
---+------+----+------
1  | a1   | 1  | a2
1  | a1   | 3  | b2
2  | b1   | 1  | a2
2  | b1   | 3  | b2

INNER JOIN:
當你想根據table1.id = table2.id你可以使用的關係為上面的結果添加一個過濾器時INNER JOIN

SELECT * FROM table1, table2 WHERE table1.id = table2.id
--[OR]
SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id

--[Results:]
id | name | id | name 
---+------+----+------
1  | a1   | 1  | a2

LEFT [OUTER] JOIN:
如果你想在上面的結果中使用其中一個表的所有行 - 具有相同的關係 - 你可以使用LEFT JOIN:(
對於RIGHT JOIN只需更改表的位置)

SELECT * FROM table1, table2 WHERE table1.id = table2.id 
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
--[OR]
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id

--[Results:]
id | name | id   | name 
---+------+------+------
1  | a1   | 1    | a2
2  | b1   | Null | Null

FULL OUTER JOIN:
當您還希望在結果中包含其他表的所有行時,您可以使用FULL OUTER JOIN

SELECT * FROM table1, table2 WHERE table1.id = table2.id
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
UNION ALL
SELECT Null, Null, * FROM table2 WHERE Not table2.id In (SELECT id FROM table1)
--[OR] (recommended for SQLite)
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
UNION ALL
SELECT * FROM table2 LEFT JOIN table1 ON table2.id = table1.id
WHERE table1.id IS NULL
--[OR]
SELECT * FROM table1 FULL OUTER JOIN table2 On table1.id = table2.id

--[Results:]
id   | name | id   | name 
-----+------+------+------
1    | a1   | 1    | a2
2    | b1   | Null | Null
Null | Null | 3    | b2

那麼,根據您的需要,您可以選擇滿足您需求的每一個;)。


簡單來說,

1. INNER JOIN或EQUI JOIN:返回僅匹配兩個表中的條件的結果集。

2. OUTER JOIN:即使條件匹配與否,也返回兩個表中所有值的結果集。

3. LEFT JOIN:返回左表中所有值的結果集,只返回與右表中的條件匹配的行。

4. RIGHT JOIN:返回右表中所有值的結果集,只返回與左表中的條件匹配的行。

5. 完全加入:完全加入和全外加入是相同的。


簡單來說:

內部聯接 - >從父表和子表中獲取常用記錄WHERE主表的主鍵與子表中的外鍵匹配。

左連接 - >

偽代碼

1.Take All records from left Table
2.for(each record in right table,) {
    if(Records from left & right table matching on primary & foreign key){
       use their values as it is as result of join at the right side for 2nd table.
    } else {
       put value NULL values in that particular record as result of join at the right side for 2nd table.
    }
  }

右連接 :與左連接完全相反。 將表的名稱放在右連接右側的LEFT JOIN中,得到與LEFT JOIN相同的輸出。

外連接 :顯示兩個表中的所有記錄No matter what 。 如果Left表中的記錄與Primary,Forieign鍵的右表不匹配,則使用NULL值作為join的結果。

示例:

讓我們現在假設2個表

1.employees , 2.phone_numbers_employees

employees : id , name 

phone_numbers_employees : id , phone_num , emp_id   

這裡,employees表是Master表,phone_numbers_employees是子表(它包含emp_id作為連接employee.id其子表的外鍵。)

內連接

記入2個表的記錄如果僱員表的主鍵(其id)與子表phone_numbers_employees(emp_id)的外鍵匹配

所以查詢將是:

SELECT e.id , e.name , p.phone_num FROM employees AS e INNER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

這裡只取主鍵=外鍵上的匹配行,如上所述。作為連接結果,主鍵=外鍵上的非匹配行被跳過。

左連接

左連接保留左表的所有行,無論是否在右表上都有匹配的行。

SELECT e.id , e.name , p.phone_num FROM employees AS e LEFT JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

外連接

SELECT e.id , e.name , p.phone_num FROM employees AS e OUTER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

從圖形上看,它看起來像:


維恩圖並沒有真正為我做這件事。

例如,它們沒有顯示交叉連接和內連接之間的任何區別,或者更一般地顯示不同類型的連接謂詞之間的任何區別,或者提供用於推理它們將如何操作的框架。

理解邏輯處理是無可替代的,無論如何都要相對簡單。

  1. 想像一下交叉連接。
  2. 針對步驟1中的所有行計算on子句,並將謂詞計算結果保留為true
  3. (僅適用於外部聯接)在步驟2中丟失的任何外部行中添加回來。

(注意:在實踐中,查詢優化器可能會找到比上面的純邏輯描述更有效的執行查詢的方法,但最終結果必須相同)

我將從完整外部聯接的動畫版本開始。 進一步說明如下。

說明

來源表

首先從CROSS JOIN (AKA笛卡爾積)開始。 它沒有ON子句,只返回兩個表中的每個行組合。

SELECT A.Colour,B.Colour from A CROSS JOIN B

內部和外部聯接具有“ON”子句謂詞。

  • 內部聯接。 為交叉連接結果中的所有行評估“ON”子句中的條件。 如果為true則返回連接的行。 否則丟棄它。
  • 左外連接。 與內部聯接相同,然後對於左表中任何不匹配的行,將這些行輸出為右表列的NULL值。
  • 正確的外部加入。 與內部聯接相同,然後對於右表中任何不匹配的行,將這些行輸出為左表列的NULL值。
  • 完全外部加入。 與內部聯接相同,然後保留左側外部聯接中的左側非匹配行,按右側外部聯接保留右側非匹配行。

一些例子

SELECT A.Colour,B.Colour from A INNER JOIN B ON A.Colour = B.Colour

以上是經典的equi join。

動畫版

SELECT A.Colour,B.Colour from A INNER JOIN B ON A.Colour NOT IN('Green','Blue')

內連接條件不一定是相等條件,也不需要引用來自兩個(或甚至任何一個)表的列。 在交叉連接的每一行上評估A.Colour NOT IN ('Green','Blue')返回。

選擇A.Colour,B.Colour from INNER JOIN B ON 1 = 1

對於交叉連接結果中的所有行,連接條件的計算結果為true,因此這與交叉連接相同。 我不會再重複16行的圖片了。

SELECT A.Colour,B.Colour from a LEFT OUTER JOIN B ON A.Colour = B.Colour

外連接的邏輯評估方式與內連接的方式相同,只是如果左表中的一行(左連接)不與右表中的任何行連接,它將保留在結果中,其值為NULL右欄。

SELECT A.Colour,B.Colour from a LEFT OUTER JOIN B ON A.Colour = B.Colour WHERE B.Colour IS NULL

這只是將前一個結果限制為僅返回B.Colour IS NULL的行。 在這種特殊情況下,這些將是保留的行,因為它們在右側表中沒有匹配,並且查詢返回表B不匹配的單個紅色行。 這被稱為反半連接。

IS NULL測試選擇一個不可為空的列或者連接條件確保將排除任何NULL值以使此模式正常工作並避免僅返回恰好具有除了未匹配的行之外,該列的NULL值。

SELECT A.Colour,B.Colour from A ROU OUTER JOIN B ON A.Colour = B.Colour

右外連接的作用類似於左外連接,除了它們保留右表中的非匹配行,並且null擴展左側列。

選擇A.Colour,B.Colour從一個完整的外部加入B A.Colour = B.Colour

完全外連接組合了左連接和右連接的行為,並保留左表和右表的不匹配行。

選擇A.Colour,B.Colour from A FULL OUTER JOIN B ON 1 = 0

交叉連接中的任何行都不匹配1=0謂詞。 使用常規外部聯接規則保留兩側的所有行,並在另一側的表中使用NULL。

SELECT COALESCE(A.Colour,B.Colour)AS顏色來自一個完整的外部連接B ON 1 = 0

通過對前面的查詢的一個小修改,可以模擬兩個表中的UNION ALL

SELECT A.Colour,B.Colour from a LEFT OUTER JOIN B ON A.Colour = B.Colour WHERE B.Colour ='Green'

請注意, WHERE子句(如果存在)在連接後邏輯運行。 一個常見錯誤是執行左外連接,然後在右表上包含一個WHERE子句,該子句最終排除不匹配的行。 以上結果執行外連接...

...然後“Where”子句運行。 NULL= 'Green'不計算為true,因此外連接保留的行最終被丟棄(連同藍色連接),有效地將連接轉換回內連接。

如果意圖僅包括B中的行,其中Color為綠色,而所有來自A的行都不包括正確的語法

SELECT A.Colour,B.Colour from a LEFT OUTER JOIN B ON A.Colour = B.Colour AND B.Colour ='Green'

SQL小提琴

請參閱SQLFiddle.com上的這些示例。


您可以使用INNER JOIN從兩個匹配的表中返回所有行。即在結果表中,所有行和列都將具有值。

OUTER JOIN結果表中可能有空列。外部聯接可以是LEFTRIGHT

LEFT OUTER JOIN 返回第一個表中的所有行,即使第二個表中沒有匹配項也是如此。

RIGHT OUTER JOIN 返回第二個表中的所有行,即使第一個表中沒有匹配項也是如此。


精確的算法INNER JOINLEFT/RIGHT OUTER JOIN如下:

  1. 從第一個表中獲取每一行: a
  2. 考慮旁邊第二個表中的所有行: (a, b[i])
  3. ON ...針對每對評估子句:ON( a, b[i] ) = true/false?
    • 當條件求值時true,返回該組合行(a, b[i])
    • 當到達第二個表的末尾沒有任何匹配時,這是一個Outer Join然後返回一個(虛擬)Null用於其他表的所有列:(a, Null)用於LEFT外連接或(Null, b)用於RIGHT外連接。這是為了確保第一個表的所有行都存在於最終結果中。

注意:ON子句中指定的條件可以是任何條件,不需要使用主鍵(並且您不需要始終引用兩個表中的列)!例如:

  • ... ON T1.title = T2.title AND T1.version < T2.version(=>將此帖子視為示例用法:僅選擇列上具有最大值的行)
  • ... ON T1.y IS NULL
  • ... ON 1 = 0 (就像樣品一樣)

注意:左連接=左外連接,右連接=右外連接。





outer-join