mysql的多表查詢總結

一.前言 

上篇講到Mysql中關鍵字執行的順序,只涉及了一張表;實際應用大部分情況下,查詢語句都會涉及到多張表格 :

1.1 多表連接有哪些分類?

1.2 針對這些分類有哪些連接方法?

1.3 這些連接方法分別作用於哪些應用場景?

這篇針對這三個點通過實例來講述,目的是窮盡所有的場景和所有的方法,並且對每個方法的使用做實例。

首先先列舉本篇用到的分類(內連接,外連接,交叉連接)和連接方法(如下):

A)內連接:join,inner join

B)外連接:left join,left outer join,right join,right outer join,union

C)交叉連接:cross join

 

二.下面以實例進行分析

兩張假設有兩張表格A和B,把表格當作一個集合,那麼表格中的記錄就是集合中的一個元素。

兩張表格如下:

TableA:TableB:

2.1 內連接(只有一種場景)

inner join 或者join(等同於inner join)

 


 
  1. select a.*, b.* from tablea a

  2. inner join tableb b

  3. on a.id = b.id

 

 


 
  1. select a.*, b.* from tablea a

  2. join tableb b

  3. on a.id = b.id

 

結果如下:

應用場景:

這種場景下得到的是滿足某一條件的A,B內部的數據;正因爲得到的是內部共有數據,所以連接方式稱爲內連接。

2.2 外連接(六種場景)

2.2.1 left join 或者left outer join(等同於left join)


 
  1. select a.*, b.* from tablea a

  2. left join tableb b

  3. on a.id = b.id

 

或者

 


 
  1. select a.*, b.* from tablea a

  2. left outer join tableb b

  3. on a.id = b.id

結果如下,TableB中更不存在的記錄填充Null:

應用場景:

這種場景下得到的是A的所有數據,和滿足某一條件的B的數據;

2.2.2  [left   join 或者left outer join(等同於left join)]  +  [where B.column is null]

 


 
  1. select a.id aid,a.age,b.id bid,b.name from tablea a

  2. left join tableb b

  3. on a.id = b.id

  4. Where b.id is null

結果如下:

應用場景:

這種場景下得到的是A中的所有數據減去"與B滿足同一條件 的數據",然後得到的A剩餘數據;

2.2.3  right join 或者fight outer join(等同於right join)

 


 
  1. select a.id aid,a.age,b.id bid,b.name from tablea a

  2. right join tableb b

  3. on a.id = b.id

結果如下,TableB中更不存在的記錄填充Null:

 

應用場景:

這種場景下得到的是B的所有數據,和滿足某一條件的A的數據;

2.2.4 [left   join 或者left outer join(等同於left join)]  +  [where A.column is null]

 


 
  1. select a.id aid,a.age,b.id bid,b.name from tablea a

  2. right join tableb b

  3. on a.id = b.id

  4. where a.id is null

結果如下:

 


應用場景:

這種場景下得到的是B中的所有數據減去 "與A滿足同一條件 的數據“,然後得到的B剩餘數據;

2.2.5 full join (mysql不支持,但是可以用 left join  union right join代替)

 


 
  1. select a.id aid,a.age,b.id bid,b.name from tablea a

  2. left join tableb b

  3. on a.id = b.id

  4. union

  5. select a.id aid,a.age,b.id bid,b.name from tablea a

  6. right join tableb b

  7. on a.id = b.id

union過後,重複的記錄會合並(id爲2,3,4的三條記錄),所以結果如下:

 

應用場景:

 

這種場景下得到的是滿足某一條件的公共記錄,和獨有的記錄

2.2.6 full join + is null(mysql不支持,但是可以用 (left join + is null) union (right join+isnull代替)

 


 
  1. select a.id aid,a.age,b.id bid,b.name from tablea a

  2. left join tableb b

  3. on a.id = b.id

  4. where b.id is null

  5. union

  6. select a.id aid,a.age,b.id bid,b.name from tablea a

  7. right join tableb b

  8. on a.id = b.id

  9. where a.id is null

結果如下:

 

應用場景:

這種場景下得到的是A,B中不滿足某一條件的記錄之和

注:上面共有其中七(2^3-1)種應用場景,還有一種是全空白,那就是什麼都不查,七種情形包含了實際應用所有可能的場景

2.3 交叉連接 (cross join)

2.3.1 實際應用中還有這樣一種情形,想得到A,B記錄的排列組合,即笛卡兒積,這個就不好用集合和元素來表示了。需要用到cross join:

 


 
  1. select a.id aid,a.age,b.id bid,b.name from tablea a

  2. cross join tableb b

 

2.3.2 還可以爲cross  join指定條件 (where):


 
  1. select a.id aid,a.age,b.id bid,b.name from tablea a

  2. cross join tableb b

  3. where a.id = b.id

結果如下;

注:這種情況下實際上實現了內連接的效果

三 注意事項

上面仍然存在遺漏,那就是mysql對sql語句的容錯問題,即在sql語句不完全符合書寫建議的情況,mysql會允許這種情況,儘可能地解釋它:

3.1 一般cross join後面加上where條件,但是用cross join+on也是被解釋爲cross join+where;

3.2 一般內連接都需要加上on限定條件,如上面場景2.1;如果不加會被解釋爲交叉連接;

3.3 如果連接表格使用的是逗號,會被解釋爲交叉連接;

注:sql標準中還有union join和natural  inner join,mysql不支持,而且本身也沒有多大意義,其結果可以用上面的幾種連接方式得到

總結:總結了mysql所有連接方法,其中有一些是之前沒有注意到的問題,平時開發也都不外乎這些

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章