風雨無阻

          內連接和外連接區別

          在之前,我對MSSQL中的內連接和外連接所得出的數據集不是很清楚。這幾天重新溫習了一下SQL的書本,現在的思路應該是很清楚了,現在把自己的理解發出來給大家溫習下。希望和我一樣對SQL的連接語句不太理解的朋友能夠有所幫助。(發這么菜的教程,各位大大們別笑話偶了,呵:D )

          有兩個表A和表B。
          表A結構如下:
          Aid:int;標識種子,主鍵,自增ID
          Aname:varchar

          數據情況,即用select * from A出來的記錄情況如下圖1所示:


          圖1:A表數據

          表B結構如下:
          Bid:int;標識種子,主鍵,自增ID
          Bnameid:int

          數據情況,即用select * from B出來的記錄情況如下圖2所示:



          圖2:B表數據

          為了把Bid和Aid加以區分,不讓大家有誤解,所以把Bid的起始種子設置為100。
          有SQL基本知識的人都知道,兩個表要做連接,就必須有個連接字段,從上表中的數據可以看出,在A表中的Aid和B表中的Bnameid就是兩個連接字段。
          下圖3說明了連接的所有記錄集之間的關系:



          圖3:連接關系圖

          現在我們對內連接和外連接一一講解。
          1.內連接:利用內連接可獲取兩表的公共部分的記錄,即圖3的記錄集C
          語句如下:Select * from A JOIN B ON A.Aid=B.Bnameid
          運行結果如下圖4所示:



          圖4:內連接數據

          其實select * from A,B where A.Aid=B.Bnameid與Select * from A JOIN B ON A.Aid=B.Bnameid的運行結果是一樣的。
          2.外連接:外連接分為兩種,一種是左連接(Left JOIN)和右連接(Right JOIN)
            (1)左連接(Left JOIN):即圖3公共部分記錄集C+表A記錄集A1。     
               語句如下:select * from A Left JOIN B ON A.Aid=B.Bnameid
               運行結果如下圖5所示:



          圖5:左連接數據

               說明:
                     在語句中,A在B的左邊,并且是Left Join,所以其運算方式為:A左連接B的記錄=圖3公共部分記錄集C+表A記錄集A1
                     在圖3中即記錄集C中的存在的Aid為:2 3 6 7 8           
                     圖1中即表A所有記錄集A中存在的Aid為:1 2 3 4 5 6 7 8 9
                     表A記錄集A1中存在的Aid=(圖1中即A表中所有Aid)-(圖3中即記錄集C中存在的Aid),最終得出為:1 4 5 9
                     由此得出圖5中A左連接B的記錄=圖3公共部分記錄集C+表A記錄集A1,
                     最終得出的結果圖5中可以看出Bnameid及Bid非NULL的記錄都為圖3公共部分記錄集C中的記錄;Bnameid及Bid為NULL的Aid為1 4 5 9的四筆記錄就是表A記錄集A1中存在的Aid。

            (2)右連接(Right JOIN):即圖3公共部分記錄集C+表B記錄集B1。
               語句如下:select * from A Right JOIN B ON A.Aid=B.Bnameid
               運行結果如下圖6所示:



          圖6:右連接數據

               說明:
                     在語句中,A在B的左邊,并且是Right Join,所以其運算方式為:A右連接B的記錄=圖3公共部分記錄集C+表B記錄集B1
                     在圖3中即記錄集C中的存在的Aid為:2 3 6 7 8           
                     圖2中即表B所有記錄集B中存在的Bnameid為:2 3 6 7 8 11
                     表B記錄集B1中存在的Bnameid=(圖2中即B表中所有Bnameid)-(圖3中即記錄集C中存在的Aid),最終得出為:11
                     由此得出圖6中A右連接B的記錄=圖3公共部分記錄集C+表B記錄集B1,
                     最終得出的結果圖6中可以看出Aid及Aname非NULL的記錄都為圖3公共部分記錄集C中的記錄;Aid及Aname為NULL的Aid為11的記錄就是表B記錄集B1中存在的Bnameid。
               
          總結:

          通過上面的運算解說,相信很多人已經想到,上面的情況(包括圖3的關系圖)說明的都只是A在B的左邊的情況,
          以下語句B在A的右邊的又會出現什么情況呢??
          select * from B Left JOIN A ON A.Aid=B.Bnameid
          select * from B Right JOIN A ON A.Aid=B.Bnameid

          其實對圖3左右翻轉一下就可以得出以下結論:
          select * from B Left JOIN A ON A.Aid=B.Bnameid和select * from A Right JOIN B ON A.Aid=B.Bnameid所得出的記錄集是一樣的

          select * from B Right JOIN A ON A.Aid=B.Bnameid和select * from A Left JOIN B ON A.Aid=B.Bnameid所得出的記錄集也是一樣的。

          posted on 2008-03-20 17:06 秋楓故事 閱讀(3668) 評論(3)  編輯  收藏

          評論

          # re: 內連接和外連接區別 2008-05-23 16:03 coolsenba

          不錯,一下就看懂了  回復  更多評論   

          # re: 內連接和外連接區別 2008-12-15 17:41 mida

          太謝謝了,終于懂了!!!  回復  更多評論   

          # re: 內連接和外連接區別 2008-12-23 09:36 miaomiao

          講的很清楚  回復  更多評論   


          只有注冊用戶登錄后才能發表評論。


          網站導航:
          博客園   IT新聞   Chat2DB   C++博客   博問  
           
          <2008年3月>
          2425262728291
          2345678
          9101112131415
          16171819202122
          23242526272829
          303112345

          導航

          統計

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          新聞檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 古田县| 夏河县| 湘潭市| 海宁市| 武宣县| 塔城市| 阿荣旗| 阜新市| 绥芬河市| 巩义市| 玉龙| 周口市| 九龙城区| 建始县| 密云县| 会泽县| 乌拉特中旗| 兴山县| 黔东| 安平县| 临清市| 会泽县| 清水河县| 胶南市| 芜湖县| 宜君县| 巴青县| 馆陶县| 高碑店市| 葫芦岛市| 常州市| 富阳市| 宁德市| 洱源县| 新宁县| 达拉特旗| 瑞丽市| 社旗县| 乌兰察布市| 沙田区| 安远县|