[SQL]Join的觀念
前言
在位置上很常聽到人家討論SQL的時候,Join來Join去,害我每次都會回頭(因為聽起來實在很像在叫我的名字)。
小的自認為DB與SQL的功力,一向很薄弱。
而training新人時,第一個要解釋table與table之間關係,通常也是會講到join。
我雖然大概知道join是怎麼一回事,不過有時候解釋起來,看新人一臉疑惑的表情,也是讓我頗受傷的。
所以,上次看了呂老師書上的一張圖,
真的深深覺得一張圖加兩張table的範例資料,勝過千言萬語啊。
What is 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。
-
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其實沒有多大分別。
於是,以我們的範例資料來說,這個例子會撈出
-
Select * from table1, table2
-
除了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的欄位資料。
-
Left join的SQL如下:
另外要提醒的,outer是可以省略的。而在Join裡面,Where條件扮演著什麼角色?
其實Where的條件,是用來限制Left table與Right table的Scope的。
所以where與join可以說毫無關係,因為是用來分別定義table的篩選條件,而非交集的條件。
希望不會在有朋友搞不清楚,到底什麼條件要放在join的on裡面,
什麼條件該放在where裡面。
用這張圖去思考一下,會幫您釐清許多的問題。
結論
- 上述的所有table,只是一種資料集合。也就是代表,它可以是另外一個子查詢後的結果。
- Left與Right的定義,則是被乘數與乘數的分別。
- Where只是篩選條件,拿來限制Left table與Right table的Scope。
- Inner Join沒有左右的差異,所以可以直接用兩張表的一個where 條件來表示,當然您要寫成inner join的表示法也會更符合這張圖的意義喔。
- 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/