[SQL]Join的觀念

  • 197003
  • 0
  • 2011-07-20

[SQL]Join的觀念

前言

在位置上很常聽到人家討論SQL的時候,Join來Join去,害我每次都會回頭(因為聽起來實在很像在叫我的名字)。

小的自認為DB與SQL的功力,一向很薄弱。
而training新人時,第一個要解釋table與table之間關係,通常也是會講到join。

我雖然大概知道join是怎麼一回事,不過有時候解釋起來,看新人一臉疑惑的表情,也是讓我頗受傷的。

所以,上次看了呂老師書上的一張圖,
真的深深覺得一張圖加兩張table的範例資料,勝過千言萬語啊。

 

What is join?

Join,通常稱做交集,而交集是什麼呢?望文生義,看圖說故事,各位看官就會瞭解了。

join 

這張圖,解釋了兩張表之間的關係。

兩張table,我們分別定義為Left table跟Right table。Left就是被交集的table (要稱做資料集合也可以),Right就是拿來交集的table。
就像A x B = C,我們稱A為被乘數,B為乘數,一樣的意思。

比較常看到的,Left table,就是Select * from [table1] ,這個from的table。
Right table,則是被join的那一張table,
例如

Select * from [table1]
Left join [table2] on [table1].fk=[table2].pk


在這例子,table2就是圖裡面的Right table。

而兩張table join的條件,也就是他們是靠什麼來做交集的,就是on後面的 [table1].fk=[table2].pk。
交集的條件不一定只有一個,Left table與Right table的交集後的結果,也有可能是空集合,也就是無符合的資料。

好,接著我們來給兩張表一些資料。

Table1:

PK FK
1 a1
2 a2
3 a3


Table2:

PK Description
a2 a2很棒
a3 a3很棒
a4 a4很棒

當我們現在join的條件是Table1.FK與Table2.PK。

  1. Inner Join,就代表Table1與Table2兩者,完全符合交集條件的資料集合。
    也就是上面圖裡面,兩個圈圈共同圈起來的那個部分,
    SQL的範例,通常inner join我們會直接寫
    Table1_PK Table1_FK Table2_Description
    2 a2 a2很棒
    3 a3 a3很棒
    • Select * from table1, table2
      Where table1.FK=table2.PK


      Inner Join代表的是兩個table共同的部分才要篩選出來,所以誰是Left,誰是Right其實沒有多大分別。

      於是,以我們的範例資料來說,這個例子會撈出
  2. 除了Inner以外,當然就是Outer了。
    Outer又分兩種,一種是左邊的Outer,一種是右邊的Outer。
    什麼叫做左邊的Outer,在我們的圖裡面,就是左邊的圈圈全都要出來,而符合交集條件的右邊圈圈,資料也要帶出來。
    Table1_PK Table1_FK Table2_Description
    1 null null
    2 a2 a2很棒
    3 a3 a3很棒
    Table1_PK Table2_PK Table2_Description
    2 a2 a2很棒
    3 a3 a3很棒
    null a4 a4很棒
    • Left join的SQL如下:
      Select * from table1
      Left outer join table2 on table1.FK = table2.PK


      在這例子,代表了table1就是我們的Left table,所以Left outer join後,table1所有資料都應該顯示出來,
      而符合table1.FK = table2.PK條件的資料,應該會帶出Table2的相關欄位資料。

    • Right join的SQL如下:
      Select * from table1
      Right outer join table2 on table1.FK = table2.PK


      在這例子,table2代表我們的Right table,所以Table2所有資料應該顯示出來,並且符合交集條件的資料,應該有table1的欄位資料。

 

另外要提醒的,outer是可以省略的。而在Join裡面,Where條件扮演著什麼角色?
其實Where的條件,是用來限制Left table與Right table的Scope的。

所以where與join可以說毫無關係,因為是用來分別定義table的篩選條件,而非交集的條件。

希望不會在有朋友搞不清楚,到底什麼條件要放在join的on裡面,
什麼條件該放在where裡面。

用這張圖去思考一下,會幫您釐清許多的問題。

 

結論

  1. 上述的所有table,只是一種資料集合。也就是代表,它可以是另外一個子查詢後的結果。
  2. Left與Right的定義,則是被乘數與乘數的分別。
  3. Where只是篩選條件,拿來限制Left table與Right table的Scope。
  4. Inner Join沒有左右的差異,所以可以直接用兩張表的一個where 條件來表示,當然您要寫成inner join的表示法也會更符合這張圖的意義喔。
  5. Outer Join的Outer可以省略,但Left或Right則不能省略。

複雜或多層的Join,只是像寫程式剝洋蔥或穿衣服一樣,可以想像一行一行的join下來,每次都只有一個被乘數和乘數在做交集而已。
就像
a1 x a2 x a3 x a4,您會先計算a1 x a2後,再 x a3,之後的結果再 x a4一樣。

補充(2011/07/20):很讚的說明:http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html


blog 與課程更新內容,請前往新站位置:http://tdd.best/