天天看點

圖解MySQL 内連接配接、外連接配接、左連接配接、右連接配接、全連接配接……太多了

用兩個表(a_table、b_table),關聯字段a_table.a_id和b_table.b_id來示範一下MySQL的内連接配接、外連接配接( 左(外)連接配接、右(外)連接配接、全(外)連接配接)。

MySQL版本:Server version: 5.6.31 MySQL Community Server (GPL)

資料庫表:a_table、b_table

主題:内連接配接、左連接配接(左外連接配接)、右連接配接(右外連接配接)、全連接配接(全外連接配接)

前提

​<code>​ ​</code>​

​<code>​CREATE TABLE `a_table` (​</code>​

​<code>​ `a_id` int(11) DEFAULT NULL,​</code>​

​<code>​ `a_name` varchar(10) DEFAULT NULL,​</code>​

​<code>​ `a_part` varchar(10) DEFAULT NULL​</code>​

​<code>​) ENGINE=InnoDB DEFAULT CHARSET=utf8​</code>​

​<code>​CREATE TABLE `b_table` (​</code>​

​<code>​ `b_id` int(11) DEFAULT NULL,​</code>​

​<code>​ `b_name` varchar(10) DEFAULT NULL,​</code>​

​<code>​ `b_part` varchar(10) DEFAULT NULL​</code>​

圖解MySQL 内連接配接、外連接配接、左連接配接、右連接配接、全連接配接……太多了

一、内連接配接

關鍵字:inner join on

語句:select * from a_table a inner join b_table bona.a_id = b.b_id;

執行結果:

圖解MySQL 内連接配接、外連接配接、左連接配接、右連接配接、全連接配接……太多了

說明:組合兩個表中的記錄,傳回關聯字段相符的記錄,也就是傳回兩個表的交集(陰影)部分。

圖解MySQL 内連接配接、外連接配接、左連接配接、右連接配接、全連接配接……太多了

二、左連接配接(左外連接配接)

關鍵字:left join on / left outer join on

語句:select * from a_table a left join b_table bona.a_id = b.b_id;

說明:

left join 是left outer join的簡寫,它的全稱是左外連接配接,是外連接配接中的一種。

左(外)連接配接,左表(a_table)的記錄将會全部表示出來,而右表(b_table)隻會顯示符合搜尋條件的記錄。右表記錄不足的地方均為NULL。

圖解MySQL 内連接配接、外連接配接、左連接配接、右連接配接、全連接配接……太多了

三、右連接配接(右外連接配接)

關鍵字:right join on / right outer join on

語句:select * from a_table a right outer join b_table b on a.a_id = b.b_id;

right join是right outer join的簡寫,它的全稱是右外連接配接,是外連接配接中的一種。

與左(外)連接配接相反,右(外)連接配接,左表(a_table)隻會顯示符合搜尋條件的記錄,而右表(b_table)的記錄将會全部表示出來。左表記錄不足的地方均為NULL。

圖解MySQL 内連接配接、外連接配接、左連接配接、右連接配接、全連接配接……太多了

四、全連接配接(全外連接配接)

MySQL目前不支援此種方式,可以用其他方式替代解決。

五、補充,MySQL如何執行關聯查詢

MySQL認為任何一個查詢都是一次“關聯”,并不僅僅是一個查詢需要到兩個表比對才叫關聯,是以在MySQL中,每一個查詢,每一個片段(包括子查詢,甚至基于單表查詢)都可以是一次關聯。

目前MySQL關聯執行的政策很簡單:MySQL對任何關聯都執行嵌套循環關聯操作,即MySQL先在一個表中循環取出單條資料,然後在嵌套循環到下一個表中尋找比對的行,依次下去,直到找到所有表中比對的行為止。然後根據各個表比對的行,傳回查詢中需要的各個列。請看下面的例子中的簡單的查詢:

查詢語句:select tbl1.col1, tbl2.col2 from tbl1 inner join tbl2 using(col3) where tbl1.col1 in (5, 6);

假設MySQL按照查詢中的表順序進行關聯操作,我們則可以用下面的僞代碼表示MySQL将如何完成這個查詢:

​<code>​outer_iter = iterator over tbl1 where col1 in (5, 6)​</code>​

​<code>​outer_row = outer_iter.next​</code>​

​<code>​while outer_row​</code>​

​<code>​ inner_iter = iterator over tbl2 where col3 = outer_row.col3​</code>​

​<code>​ inner_row = inner_iter.next​</code>​

​<code>​ while inner_row​</code>​

​<code>​ output [ outer_row.col1, inner_row.col2]​</code>​

​<code>​ inner_row = inner_iter.next​</code>​

​<code>​ end​</code>​

​<code>​ outer_row = outer_iter.next​</code>​

​<code>​end​</code>​

​<code>​ ​</code>​上面的執行計劃對于單表查詢和多表關聯查詢都适用,如果是一個單表查詢,那麼隻需要上面外層的基本操作。對于外連接配接,上面的執行過程仍然适用。例如,我們将上面的查詢語句修改如下:

select tbl1.col1, tbl2.col2 from tbl1 left outer join tbl2 using(col3) where tbl1.col1 in (5, 6);

那麼,對應的僞代碼如下:

​<code>​ if inner_row​</code>​

​<code>​ while inner_row​</code>​

​<code>​ output [ outer_row.col1, inner_row.col2]​</code>​

​<code>​ inner_row = inner_iter.next​</code>​

​<code>​ end​</code>​

​<code>​ else​</code>​

​<code>​ output [ outer_row.col1, null]​</code>​

​<code>​ outer_row = outer_iter.next​</code>​