<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    朋的博客

    MySQL資料,Java技術,管理思想,博弈論,Ajax,XP極限編程,H.264,HEVC,HDR
    隨筆 - 86, 文章 - 59, 評論 - 1069, 引用 - 0
    數據加載中……

    MySQL的 連接/聯結(Join)語法(原創!)

    MySQL的聯結(Join)語法

    1.內聯結、外聯結、左聯結、右聯結的含義及區別:

    ?

    在講MySQLJoin語法前還是先回顧一下聯結的語法,呵呵,其實連我自己都忘得差不多了,那就大家一起溫習吧(如果內容有錯誤或有疑問,可以來信咨詢:陳朋奕 chenpengyi#gmail.com),國內關于MySQL聯結查詢的資料十分少,相信大家在看了本文后會對MySQL聯結語法有相當清晰的了解,也不會被Oracle的外聯結的(“+”號)弄得糊涂了。

    ?

    SQL標準中規劃的(Join)聯結大致分為下面四種:

    1.? 內聯結:將兩個表中存在聯結關系的字段符合聯結關系的那些記錄形成記錄集的聯結。

    2.? 外聯結:分為外左聯結和外右聯結。

    左聯結AB表的意思就是將表A中的全部記錄和表B中聯結的字段與表A的聯結字段符合聯結條件的那些記錄形成的記錄集的聯結,這里注意的是最后出來的記錄集會包括表A的全部記錄。

    右聯結AB表的結果和左聯結BA的結果是一樣的,也就是說:

    Select A.name B.name From A Left Join B On A.id=B.id

    Select A.name B.name From B Right Join A on B.id=A.id執行后的結果是一樣的。

    3.全聯結:將兩個表中存在聯結關系的字段的所有記錄取出形成記錄集的聯結(這個不需要記憶,只要是查詢中提到了的表的字段都會取出,無論是否符合聯結條件,因此意義不大)。

    4.無聯結:不用解釋了吧,就是沒有使用聯結功能唄,也有自聯結的說法。

    ?

    這里我有個比較簡便的記憶方法,內外聯結的區別是內聯結將去除所有不符合條件的記錄,而外聯結則保留其中部分。外左聯結與外右聯結的區別在于如果用A左聯結BA中所有記錄都會保留在結果中,此時B中只有符合聯結條件的記錄,而右聯結相反,這樣也就不會混淆了。其實大家回憶高等教育出版社出版的《數據庫系統概論》書中講到關系代數那章(就是將笛卡兒積和投影那章)的內容,相信不難理解這些聯結功能的內涵。

    ?

    2.? MySQL聯結(Join)的語法

    ?

    MySQL支持Select和某些UpdateDelete情況下的Join語法,具體語法上的細節有:

    ?

    table_references:

    ??? table_reference [, table_reference] …

    ?

    table_reference:

    ??? table_factor

    ? | join_table

    ?

    table_factor:

    ??? tbl_name [[AS] alias]

    ??????? [{USE|IGNORE|FORCE} INDEX (key_list)]

    ? | ( table_references )

    ? | { OJ table_reference LEFT OUTER JOIN table_reference

    ??????? ON conditional_expr }

    ?

    join_table:

    ??? table_reference [INNER | CROSS] JOIN table_factor [join_condition]

    ? | table_reference STRAIGHT_JOIN table_factor

    ? | table_reference STRAIGHT_JOIN table_factor ON condition

    ? | table_reference LEFT [OUTER] JOIN table_reference join_condition

    ? | table_reference NATURAL [LEFT [OUTER]] JOIN table_factor

    ? | table_reference RIGHT [OUTER] JOIN table_reference join_condition

    ? | table_reference NATURAL [RIGHT [OUTER]] JOIN table_factor

    ?

    join_condition:

    ??? ON conditional_expr | USING (column_list)

    ?

    上面的用法摘自權威資料,不過大家看了是否有點暈呢?呵呵,應該問題主要還在于table_reference是什么,table_factor又是什么?這里的table_reference其實就是表的引用的意思,因為在MySQL看來,聯結就是一種對表的引用,因此把需要聯結的表定義為table_reference,同時在SQL Standard中也是如此看待的。而table_factor則是MySQL對這個引用的功能上的增強和擴充,使得引用的表可以是括號內的一系列表,如下面例子中的JOIN后面括號:

    ?

    SELECT * FROM t1 LEFT JOIN (t2, t3, t4) ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)

    ?

    這個語句的執行結果和下面語句其實是一樣的:

    ?

    SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)

    ???????????????? ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)

    ?

    這兩個例子不僅讓我們了解了MySQLtable_factortable_reference含義,同時能理解一點CROSS JOIN的用法,我要補充的是在MySQL現有版本中CROSS JOIN的作用和INNER JOIN是一樣的(雖然在SQL Standard中是不一樣的,然而在MySQL中他們的區別僅僅是INNER JOIN需要附加ON參數的語句,而CROSS JOIN不需要)。

    既然說到了ON語句,那就解釋一下吧,ON語句其實和WHERE語句功能大致相當,只是這里的ON語句是專門針對聯結表的,ON語句后面的條件的要求和書寫方式和WHERE語句的要求是一樣的,大家基本上可以把ON當作WHERE用。

    大家也許也看到了OJ table_reference LEFT OUTER JOIN table_reference這個句子,這不是MySQL的標準寫法,只是為了和ODBCSQL語法兼容而設定的,我很少用,Java的人更是不會用,所以也不多解釋了。

    那下面就具體講講簡單的JOIN的用法了。首先我們假設有2個表AB,他們的表結構和字段分別為:

    ?

    A

    ID

    Name

    1

    Tim

    2

    Jimmy

    3

    John

    4

    Tom

    B

    ID

    Hobby

    1

    Football

    2

    Basketball

    2

    Tennis

    4

    Soccer

    ?

    1.? 內聯結:

    Select A.Name B.Hobby from A, B where A.id = B.id,這是隱式的內聯結,查詢的結果是:

    Name

    Hobby

    Tim

    Football

    Jimmy

    Basketball

    Jimmy

    Tennis

    Tom

    Soccer

    它的作用和 Select A.Name from A INNER JOIN B ON A.id = B.id是一樣的。這里的INNER JOIN換成CROSS JOIN也是可以的。

    2.? 外左聯結

    Select A.Name from A Left JOIN B ON A.id = B.id,典型的外左聯結,這樣查詢得到的結果將會是保留所有A表中聯結字段的記錄,若無與其相對應的B表中的字段記錄則留空,結果如下:

    Name

    Hobby

    Tim

    Football

    Jimmy

    BasketballTennis

    John

    ?

    Tom

    Soccer

    所以從上面結果看出,因為A表中的John記錄的ID沒有在B表中有對應ID,因此為空,但Name欄仍有John記錄。

    3.? 外右聯結

    如果把上面查詢改成外右聯結:Select A.Name from A Right JOIN B ON A.id = B.id,則結果將會是:

    Name

    Hobby

    Tim

    Football

    Jimmy

    Basketball

    Jimmy

    Tennis

    Tom

    Soccer

    這樣的結果都是我們可以從外左聯結的結果中猜到的了。

    說到這里大家是否對聯結查詢了解多了?這個原本看來高深的概念一下子就理解了,恍然大悟了吧(呵呵,開玩笑了)?最后給大家講講MySQL聯結查詢中的某些參數的作用:

    ?

    1USING (column_list):其作用是為了方便書寫聯結的多對應關系,大部分情況下USING語句可以用ON語句來代替,如下面例子:

    ?

    a LEFT JOIN b USING (c1,c2,c3),其作用相當于下面語句

    a LEFT JOIN b ON a.c1=b.c1 AND a.c2=b.c2 AND a.c3=b.c3

    ?

    只是用ON來代替會書寫比較麻煩而已。

    ?

    2NATURAL [LEFT] JOIN:這個句子的作用相當于INNER JOIN,或者是在USING子句中包含了聯結的表中所有字段的Left JOIN(左聯結)。

    ?

    3STRAIGHT_JOIN:由于默認情況下MySQL在進行表的聯結的時候會先讀入左表,當使用了這個參數后MySQL將會先讀入右表,這是個MySQL的內置優化參數,大家應該在特定情況下使用,譬如已經確認右表中的記錄數量少,在篩選后能大大提高查詢速度。

    ?

    最后要說的就是,在MySQL5.0以后,運算順序得到了重視,所以對多表的聯結查詢可能會錯誤以子聯結查詢的方式進行。譬如你需要進行多表聯結,因此你輸入了下面的聯結查詢:

    ?

    SELECT t1.id,t2.id,t3.id

    ??? FROM t1,t2

    ??? LEFT JOIN t3 ON (t3.id=t1.id)

    ??? WHERE t1.id=t2.id;

    ?

    但是MySQL并不是這樣執行的,其后臺的真正執行方式是下面的語句:

    ?

    SELECT t1.id,t2.id,t3.id

    ??? FROM t1,(? t2 LEFT JOIN t3 ON (t3.id=t1.id)? )

    ??? WHERE t1.id=t2.id;

    ?

    這并不是我們想要的效果,所以我們需要這樣輸入:

    ?

    SELECT t1.id,t2.id,t3.id

    ??? FROM (t1,t2)

    ??? LEFT JOIN t3 ON (t3.id=t1.id)

    ??? WHERE t1.id=t2.id;

    ?

    在這里括號是相當重要的,因此以后在寫這樣的查詢的時候我們不要忘記了多寫幾個括號,至少這樣能避免很多錯誤(因為這樣的錯誤是很難被開發人員發現的)。如果對上面內容有疑問可以來信查詢:陳朋奕 chenpengyi#gmail.com,轉載請注明出處及作者。

    posted on 2005-10-17 22:53 benchensz 閱讀(51972) 評論(24)  編輯  收藏 所屬分類: 隨便寫寫(比較有用,值得看看)

    評論

    # re: MySQL的聯結(Join)語法(原創!)  回復  更多評論   

    果然清楚,謝謝樓上給這么好的講解,卻是現在網上對這個的解釋太少了,即使有也是比較無聊的。謝謝了。
    2005-10-18 12:04 | tim163

    # re: MySQL的聯結(Join)語法(原創!)  回復  更多評論   

    謝謝你的講解,以前是學的SQL SERVER的連接,看來MYSQL的連接也差不多,更深刻的理解了。
    2005-10-21 21:25 | mpshun

    # re: MySQL的聯結(Join)語法(原創!)  回復  更多評論   

    我也頂一個
    很簡潔明了,喜歡這個,不知道樓主現在是做什么工作?
    2005-10-21 22:31 | kknd

    # re: MySQL的 連接/聯結(Join)語法(原創!)  回復  更多評論   

    這個是我見過講解聯接最好的了。
    2005-11-01 17:33 | bill lee

    # re: MySQL的 連接/聯結(Join)語法(原創!)  回復  更多評論   

    引用:**********************************
    譬如你需要進行多表聯結,因此你輸入了下面的聯結查詢:

    SELECT t1.id,t2.id,t3.id
    FROM t1,t2
    LEFT JOIN t3 ON (t3.id=t1.id)
    WHERE t1.id=t2.id;

    但是MySQL并不是這樣執行的,其后臺的真正執行方式是下面的語句:

    SELECT t1.id,t2.id,t3.id
    FROM t1,( t2 LEFT JOIN t3 ON (t3.id=t1.id) )
    WHERE t1.id=t2.id;
    結束引用********************************

    請問大蝦您是怎么知道mysql后臺的執行方式?能不能給點線索,小弟實在不明白好端端的輸入怎么就給改了方式運行哪?謝謝
    2006-01-02 21:03 | 一葉小舟

    # re: MySQL的 連接/聯結(Join)語法(原創!)  回復  更多評論   

    3x,溫習了一下,真的很清楚
    2006-01-04 14:31 | lisa

    # re: MySQL的 連接/聯結(Join)語法(原創!)  回復  更多評論   

    解釋清晰。非常感謝。
    2006-02-11 15:36 | Foon

    # re: MySQL的 連接/聯結(Join)語法(原創!)  回復  更多評論   

    謝謝樓主,好東西
    2009-03-11 10:49 | ronald

    # re: MySQL的 連接/聯結(Join)語法(原創!)  回復  更多評論   

    謝謝分享,寫得很清楚,很容易看懂
    2009-03-30 18:30 | SiemenLiu

    # re: MySQL的 連接/聯結(Join)語法(原創!)[未登錄]  回復  更多評論   

    看了很多,在這里才真的明白了,謝謝
    2009-04-14 15:46 | Jun

    # re: MySQL的 連接/聯結(Join)語法(原創!)  回復  更多評論   

    受益匪淺!
    2009-04-29 10:36 | fenix

    # re: MySQL的 連接/聯結(Join)語法(原創!)  回復  更多評論   

    受益匪淺
    2010-09-25 16:32 | ai

    # 提問  回復  更多評論   

    在“2.外左聯結”中的結果第二行Hobby有兩個值,應該怎樣把這兩個值從結果集中取出來呢?
    2011-08-08 15:06 | ts

    # re: MySQL的 連接/聯結(Join)語法(原創!)  回復  更多評論   

    簡單明了
    2011-09-25 15:00 | nx

    # re: MySQL的 連接/聯結(Join)語法(原創!)  回復  更多評論   

    寫的太好了,學習啦
    2011-11-02 17:39 | 瞬間的永恒

    # re: MySQL的 連接/聯結(Join)語法(原創!)  回復  更多評論   

    SELECT b. * , k.id AS likeid , f.id AS followid ,m.username,m.domain FROM `anran_blog` AS b LEFT JOIN `anran_likes` AS k ON ( b.bid = k.bid AND k.uid ='' ) LEFT JOIN `anran_follow` AS f ON ( b.uid = f.touid and f.uid = '' ) LEFT JOIN `anran_member` as m on b.uid = m.uid where b.open = 1
    2011-12-04 17:33 | mr.doooger

    # re: MySQL的 連接/聯結(Join)語法(原創!)  回復  更多評論   

    可以幫忙解釋這句sql語句嗎?謝謝
    SELECT b. * , k.id AS likeid , f.id AS followid ,m.username,m.domain FROM `anran_blog` AS b LEFT JOIN `anran_likes` AS k ON ( b.bid = k.bid AND k.uid ='' ) LEFT JOIN `anran_follow` AS f ON ( b.uid = f.touid and f.uid = '' ) LEFT JOIN `anran_member` as m on b.uid = m.uid where b.open = 1
    2011-12-04 17:34 | mr.doooger

    # re: MySQL的 連接/聯結(Join)語法(原創!)  回復  更多評論   

    多謝,講的不錯
    2012-08-20 15:49 | juffun

    # re: MySQL的 連接/聯結(Join)語法(原創!)[未登錄]  回復  更多評論   

    大概懂了些..謝謝了
    2012-11-29 21:01 | cone

    # re: MySQL的 連接/聯結(Join)語法(原創!)  回復  更多評論   

    謝謝大哥,大哥辛苦了!
    2013-09-08 20:13 | Ice_Xue

    # re: MySQL的 連接/聯結(Join)語法(原創!)  回復  更多評論   

    很激動啊,解決了我一個大問題,上學的時候沒好好學,現在要用才搞懂了!
    2013-09-08 20:23 | Ice_Xue

    # re: MySQL的 連接/聯結(Join)語法(原創!)[未登錄]  回復  更多評論   

    Select A.Name from A Left JOIN B ON A.id = B.id

    這個sql查詢列中沒有hobby,但是查詢結果中卻出現了hobby,確定不是sql寫錯了?
    2014-11-14 10:41 | tiger

    # re: MySQL的 連接/聯結(Join)語法(原創!)[未登錄]  回復  更多評論   

    STRAIGHT_JOIN是不是解釋錯了?。。。是強制讀取左邊的表
    STRAIGHT_JOIN is similar to JOIN, except that the left table is always read before the right table. This can be used for those (few) cases for which the join optimizer puts the tables in the wrong order.
    在左表數據量小,但優化器順序錯誤先讀右表的情況下,強制先讀左表吧。。。
    2016-01-08 16:29 | null
    主站蜘蛛池模板: 无码永久免费AV网站| 亚洲成a人片在线网站| 免费高清小黄站在线观看| 国产情侣久久久久aⅴ免费| jzzijzzij在线观看亚洲熟妇| 久久av无码专区亚洲av桃花岛| 亚洲欧洲日本在线| 永久免费无码网站在线观看| 久久久久久曰本AV免费免费| 精品国产免费人成网站| 久久久久久亚洲av无码蜜芽| 亚洲国产精品线观看不卡| 久久综合日韩亚洲精品色| 亚洲黄片手机免费观看| 日本一道在线日本一道高清不卡免费| 99精品国产成人a∨免费看| 中文字幕免费观看全部电影| 国产亚洲精品2021自在线| 亚洲日本天堂在线| 久久精品国产亚洲AV久| 78成人精品电影在线播放日韩精品电影一区亚洲 | 国产精品亚洲一区二区无码| 亚洲成aⅴ人在线观看| 亚洲国产精品自在在线观看| 国产亚洲免费的视频看| 丝袜熟女国偷自产中文字幕亚洲| 国产人成免费视频| 国产亚洲精品免费| 可以免费观看的一级毛片| 国产猛烈高潮尖叫视频免费 | 久久精品国产亚洲精品2020| 亚洲阿v天堂在线| 亚洲精品狼友在线播放| 亚洲欧洲自拍拍偷午夜色无码| 亚洲精品无码日韩国产不卡?V| 又粗又硬又黄又爽的免费视频| 俄罗斯极品美女毛片免费播放| 国产免费啪嗒啪嗒视频看看| 国产jizzjizz视频免费看| 免费女人18毛片a级毛片视频| 亚洲成人高清在线|