一直對SQL各種連接不是太懂,索性就建倆表自己動手把各種連接重新學習一遍,在實踐中自己摸索比光聽老師講要強點,最起碼印象要深刻些。
先上倆表:
表A:
SQL> create table A (id int, type int);
SQL> select * from A;
ID TYPE
---------- ----------
1 1
2 1
3 2
表B:
SQL> create table B(id int ,class int);
SQL> select * from B;
ID CLASS
---------- ----------
1 1
2 2
①先從內連接(inner join)開始:
SQL> select * from A inner join B on A.id = B.id;
ID TYPE ID CLASS
---------- ---------- ---------- ----------
1 1 1 1
2 1 2 2
內連接其實比較簡單,倆表中存在至少一個匹配時,內連接才返回。如果在B表中沒有匹配的,就不會返回該行(注:inner join和join是相同的 )執行過程:以右表(B表)爲基準,遍歷左表(A表),直到與B表的id列相同的就返回該行,寄過含有重複列,分別爲A表的id列和B表的id列。
②左外連接(left join):
SQL> select * from A left join B on A.id = b.id;
ID TYPE ID CLASS
---------- ---------- ---------- ----------
1 1 1 1
2 1 2 2
3 2
左外連接是返回左表的所有行,即使右表沒有與左表匹配的行。如果右表有與左表匹配的行,那麼右表該行也返回(注:left join 與left outer join是相同的)執行過程:以左表(A表)爲基準,遍歷右表(B表)與A表匹配的B.id。若B表存在B.id = A.id,則進行拼接,返回該行,然後繼續遍歷B表的下一條B.id查看是否還存在B.id = A.id,如果查詢完畢,就進入下一條A.id,繼續重複上述步驟。如果B.id沒有與A.id相匹配的,則顯示左表的所有項,右邊全顯示爲NULL。
③右外連接(right join):
SQL> select * from A right join B on A.id = B.id;
ID TYPE ID CLASS
---------- ---------- ---------- ----------
1 1 1 1
2 1 2 2
右外連接其實與左外連接類似,也是返回右表所有行,即使左表沒有與右表匹配的行。如果左表有與右表匹配的行,那麼左表該行也返回(right join 與right outer join相同)執行過程:以B表爲基準,其他與左外連接類似,不再贅述。
④再來加點料,來點稍微有點難度的:
SQL> select * from A left join B on A.id = B.id where B.id is NULL;
ID TYPE ID CLASS
---------- ---------- ---------- ----------
3 2
這個解釋一下爲什麼會是這個結果:在where字句之前返回的結果還是左表的所有行(如②所示),但這個where字句要求右表的id列必須爲空,所以篩選掉了前兩行id不爲空的。
⑤
SQL> select * from A right join B on A.id = B.id where A.id is NULL;
未選定行
這個右連接在沒有where字句的時候是返回右表的所有行以及左表與之匹配的行(如③所示),但這個where字句要求左表的id列必須爲空,所以所有行都被篩選掉了,其篩選的下場就成苦逼的“未選定行”了。⑥全連接(full join):
SQL> select * from A full join B on A.id = B.id;
ID TYPE ID CLASS
---------- ---------- ---------- ----------
1 1 1 1
2 1 2 2
3 2
全連接是隻要其中某個表存在匹配,就會返回行。⑦
SQL> select * from A full join B on A.id = B.id where A.id is NULL or B.id is NULL;
ID TYPE ID CLASS
---------- ---------- ---------- ----------
3 2
這個全連接在沒有where條件篩選前結果如⑥,但這個where字句要求A.id爲空或者B.id爲空,顯然A.id都不爲空,所以這個條件不會返回任何行,但B.id爲空時存在一行符合條件,所以....
上訴7種情況可以用下圖概括出來,雖然不是太清楚,下載下來放大了看再對照本文還是可以看出來的。
最後介紹一下用(+)來實現的左外連接:
SQL> select * from A,B where A.id = B.id(+);
ID TYPE ID CLASS
---------- ---------- ---------- ----------
1 1 1 1
2 1 2 2
3 2
(+)可以來這樣理解:(+)寫在哪個表上,就表示哪個表時匹配表,這裏(+)寫在B表上,就表示以A爲基礎表,顯示A表的所有記錄,B表不足的部分用NULL來填充,所以這個就跟左外連接效果一樣(注;(+)只能用where連接,不能用on)。
同理用(+)來實現右外連接:
SQL> select * from A,B where A.id(+) = B.id;
ID TYPE ID CLASS
---------- ---------- ---------- ----------
1 1 1 1
2 1 2 2
原理同上,不再贅述。
相關文章:SQL左右連接中的on and和on where的區別
尊重版權,請保留下方二維碼以及本文鏈接:SQL joins
歡迎關注行者摩羅微信公衆號(xingzhemoluo),共同交流編程經驗,掃描下方二維碼即可;