SQL joins

     一直對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),共同交流編程經驗,掃描下方二維碼即可;


發佈了41 篇原創文章 · 獲贊 14 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章