HelloWorld 善戰者,求之于勢,不責于人;故能擇人而任勢。

          知止而后有定,定而后能靜,靜而后能安,安而后能慮,慮而后能得。物有本末,事有終始。知所先后,則近道矣。

            BlogJava :: 首頁 ::  :: 聯系 ::  :: 管理 ::
            167 隨筆 :: 1 文章 :: 40 評論 :: 0 Trackbacks

          原文作者 外來物種
          地址 http://blog.csdn.net/dmlk31/archive/2008/01/02/2010216.aspx

          本文收集了網上關于Left join , Right Join, Inner Join 的相關內容,非常實用,對于理解原理和具體應用都很有幫助!

          一.先看一些最簡單的例子

          例子

          Table A
          aid   adate
          1      a1
          2      a2
          3      a3

          TableB

          bid bdate
          1    b1
          2    b2
          4    b4
          兩個表a,b相連接,要取出id相同的字段
          select * from a inner join b on a.aid = b.bid這是僅取出匹配的數據.
          此時的取出的是:
          1 a1 b1
          2 a2 b2

          那么left join 指:
          select * from a left join b on a.aid = b.bid
          首先取出a表中所有數據,然后再加上與a,b匹配的的數據
          此時的取出的是:
          1 a1 b1
          2 a2 b2
          3 a3 空字符

          同樣的也有right join
          指的是首先取出b表中所有數據,然后再加上與a,b匹配的的數據
          此時的取出的是:
          1 a1 b1
          2 a2 b2
          4 空字符 b4

          LEFT JOIN 或 LEFT OUTER JOIN。
          左向外聯接的結果集包括 LEFT OUTER 子句中指定的左表的所有行,而不僅僅是聯接列所匹配的行。如果左表的某行在右表中沒有匹配行,則在相關聯的結果集行中右表的所有選擇列表列均為空值

          二. left join/right join/inner join操作演示

          表A記錄如下:
          aID        aNum
          1           a20050111
          2           a20050112
          3           a20050113
          4           a20050114
          5           a20050115


          表B記錄如下:
          bID        bName
          1            2006032401
          2           2006032402
          3           2006032403
          4           2006032404
          8           2006032408

          實驗如下:
          1.    left join
          sql語句如下:
          SELECT * FROM A
          LEFT JOIN B 
          ON A.aID = B.bID

          結果如下:
          aID        aNum                   bID           bName
          1            a20050111         1               2006032401
          2            a20050112         2              2006032402
          3            a20050113         3              2006032403
          4            a20050114         4              2006032404
          5            a20050115         NULL       NULL

          (所影響的行數為 5 行)

          結果說明:
                  left join是以A表的記錄為基礎的,A可以看成左表,B可以看成右表,left join是以左表為準的.
          換句話說,左表(A)的記錄將會全部表示出來,而右表(B)只會顯示符合搜索條件的記錄(例子中為: A.aID = B.bID).
          B表記錄不足的地方均為NULL.


          2.    right join
          sql語句如下:
          SELECT * FROM A
          RIGHT JOIN B 
          ON A.aID = B.bID

          結果如下:
          aID        aNum                   bID           bName
          1            a20050111         1               2006032401
          2            a20050112         2              2006032402
          3            a20050113         3              2006032403
          4            a20050114         4              2006032404
          NULL    NULL                8              2006032408

          (所影響的行數為 5 行)

          結果說明:
                  仔細觀察一下,就會發現,和left join的結果剛好相反,這次是以右表(B)為基礎的,A表不足的地方用NULL填充.


          3.inner join
          sql語句如下:
          SELECT * FROM A
          INNERJOIN B 
          ON A.aID = B.bID

          結果如下:
          aID        aNum                   bID           bName
          1            a20050111         1               2006032401
          2            a20050112         2              2006032402
          3            a20050113         3              2006032403
          4            a20050114         4              2006032404


          結果說明:
                  很明顯,這里只顯示出了 A.aID = B.bID的記錄.這說明inner join并不以誰為基礎,它只顯示符合條件的記錄.


          -----------------[以下為網上的一點資料]------------------
          LEFT JOIN操作用于在任何的 FROM 子句中,組合來源表的記錄。使用 LEFT JOIN 運算來創建一個左邊外部聯接。左邊外部聯接將包含了從第一個(左邊)開始的兩個表中的全部記錄,即使在第二個(右邊)表中并沒有相符值的記錄。

          語法:
          FROM table1 LEFT JOIN table2 ON table1.field1 compopr table2.field2

          說明:
          ① table1, table2參數用于指定要將記錄組合的表的名稱。
          ② field1, field2參數指定被聯接的字段的名稱。且這些字段必須有相同的數據類型及包含相同類型的數據,但它們不需要有相同的名稱。
          ③ compopr參數指定關系比較運算符:"=", "<", ">", "<=", ">=" 或 "<>"。
          ④ 如果在INNER JOIN操作中要聯接包含Memo 數據類型或 OLE Object 數據類型數據的字段,將會發生錯誤。

          三.相關的復雜的解釋和實例

          簡介: 外部連接和自聯接 inner join(等值連接) 只返回兩個表中聯結字段相等的行 left join(左聯接) 返回包括左表中的所有記錄和右表中聯結字段相等的記錄 right join(右聯接) 返回包括右表中的所有記錄和左表中聯結字段相等的記錄 on 指定表間聯結字段及其關系的等號 "=" 表達式, 返回 true 或 false. 當表達式返回 true 時, 則查詢中包含該記錄. ! 外部連接只能操作已存在于數據庫中的數據
          update (ctarticle as a left join ctclass as c on a.classid = c.classid) left join cttag as b on a.articleid = b.articleid
          set tag=tag+' ', b.articleid=a.articleid, b.classid=a.classid, b.nclassid=a.nclassid
          where a.classid=23 and a.nclassid=0 and tagid is not null

          update (ctarticle as a left join (ctnclass as c left join ctclass as d on c.classid = d.classid) on a.nclassid = c.nclassid and a.classid = c.classid) left join cttag as b on a.articleid = b.articleid set tag=d.class+' '+c.nclass, b.articleid=a.articleid, b.classid=a.classid, b.nclassid=a.nclassid where a.classid=23 and a.nclassid=197;

          更新操作
          左連接中數據的篩選
          insert into cttag(articleid,classid,nclassid) select a.articleid,a.classid,a.nclassid from ctarticle a left join cttag b on a.articleid=b.articleid where b.articleid is null

          //本語句功能為, 顯示主表的全部內容, 插入數據到副表中沒有的數據
          //主要作用為: 讓數據減少冗余

          上例中的延續
          select a.*, b.*, c.*, d.* from cttag as d left join ((ctarticle as a left join ctclass as b on a.classid=b.classid) left join ctnclass as c on a.nclassid=c.nclassid) on d.articleid=a.articleid;

          顯示文章表中的全部, 調用類別表中的欄目
          select a.*, b.*, c.* from (ctarticle a left join ctclass b on a.classid=b.classid) left join ctnclass c on a.nclassid=c.nclassid

          //作用, 有時在文章表中包含了在個別類別表中沒有的數據, 用這個語法可以讀出文章表的全部數據
          //a 為 文章表, b 為主類別, c 為子類別

          同上例, 選擇追加數據時加上空格
          insert into cttag(articleid,classid,nclassid,tag) select a.articleid,a.classid,a.nclassid,d.class+' '+c.nclass
          from (ctarticle as a left join (ctnclass c left join ctclass d on c.classid=d.classid) on a.classid=c.classid and a.nclassid=c.nclassid) left join cttag as b on a.articleid = b.articleid where a.classid=4 and a.nclassid=154;

          連接n個表, 并追加數據到其中一個表, n=4
          insert into cttag(articleid,classid,nclassid,tag) select a.articleid,a.classid,a.nclassid,d.class+c.nclass
          from (ctarticle as a left join (ctnclass c left join ctclass d on c.classid=d.classid) on a.classid=c.classid and a.nclassid=c.nclassid) left join cttag as b on a.articleid = b.articleid where a.classid=1 and a.nclassid=1;

          //解讀
          插入到 表2(欄1,欄2,欄3,欄4)
          選擇 別名a.欄1, 別名a.欄2, 別名a.欄3, 別名d.欄4 加上 別名c.欄5
          從 (表1 別名a 左連接 (表3 別名c 左連接 表4 別名d 在 別名c.欄2 等于 別名d.欄2) 在 別名a.欄2 等于 別名c.欄2 和 別名a.欄3=別名c.欄3) 左連接 表2 別名b 在 別名a.欄1 等于 別名b.欄1 在那里 別名a.欄2=1 和 別名a.欄3=1

          連接兩個表, 并追加數據到其中一個表
          insert into cttag(articleid,classid,nclassid)
          select a.articleid,a.classid,a.nclassid
          from ctarticle as a left join cttag as b on a.articleid = b.articleid where a.classid=1 and a.nclassid=1;

          //解讀
          插入到 表2(欄1,欄2,欄3)
          選擇 別名a.欄1, 別名a.欄2, 別名a.欄3
          從 表1 別名a 左連接 表2 別名b 在 別名a.欄1 等于 別名b.欄1 在那里 別名a.欄4=1 和 別名a.欄5=1

          左連接

          同步兩表的數據
          update ctarticle a inner join cttag b on a.articleid = b.articleid set b.classid=a.classid, b.nclassid=a.nclassid;

          //解讀
          更新 表1 別名a 聯接 表2 別名2 在 別名a.欄1 等于 別名b.欄1 設置 別名b.欄2 更新為 別名a.欄2, 別名b.欄3 更新為 別名a.欄3

          右外連接
          select a.*, b.* from bunclass a right join ctclass b on a.classid=b.classid where a.nclassid=20

          查詢別名 a,b 表, 只匹配 b 表中的內容.

          添加數據到連接表之一
          insert into cttag ( tag, articleid ) select top 1 b.tag, a.articleid from ctarticle as a left join cttag as b on a.articleid = b.articleid where a.articleid order by a.articleid desc;

          變通中的用法二
          insert into bureply
          select b.*, a.classid, a.nclassid
          from article as a inner join reply as b on a.articleid = b.articleid
          where classid=50;

          實際應用中的變通
          insert into butag ( tag, articleid, classid, nclassid)
          select b.tag, a.articleid, a.classid, a.nclassid
          from article as a inner join tag as b on a.articleid = b.articleid
          where classid=24;


          添加數據到其他表
          insert into butag ( tag, articleid )
          select b.tag, a.articleid
          from article as a inner join tag as b on a.articleid = b.articleid
          where a.articleid<>false;

          //解讀
          添加到 接收表(列1,列2)
          選擇 別名b.列1, 別名a.列2
          從 表1 表名a 聯接 表2 表名b 在 別名a.列c 等于 別名b.列c
          在哪里 別名a.列c 不等于 沒有

          實際應用中的變通
          select b.tag, a.articleid, a.classid, a.nclassid
          from article as a inner join tag as b on a.articleid = b.articleid
          where a.classid=24;

          查詢
          select b.tag, a.articleid
          from article as a inner join tag as b on a.articleid = b.articleid
          where a.articleid<>false;

          //解讀
          選擇 別名b.列, 別名a.列
          從 表1 別名a 聯接 表2 別名b 在 別名a.列c = 別名b.列c
          在哪里 別名a.列c 不等于 沒有
          注: as 不是必要



          </script>

          posted on 2008-01-09 09:32 helloworld2008 閱讀(570) 評論(0)  編輯  收藏 所屬分類: SQL
          主站蜘蛛池模板: 股票| 个旧市| 拜城县| 抚宁县| 明水县| 沙湾县| 太仓市| 遂昌县| 新巴尔虎左旗| 湘乡市| 潢川县| 乌拉特后旗| 安远县| 永泰县| 耿马| 永安市| 庆城县| 左贡县| 博爱县| 通州区| 铜陵市| 澄城县| 长丰县| 韶关市| 留坝县| 塔城市| 政和县| 延津县| 宜昌市| 德阳市| 通渭县| 丹寨县| 盐池县| 余庆县| 县级市| 武夷山市| 扬中市| 井陉县| 色达县| 富顺县| 龙游县|