MySQL的聯結(Join)文法
1.内聯結、外聯結、左聯結、右聯結的含義及差別:
在講MySQL的Join文法前還是先回顧一下聯結的文法,呵呵,其實連我自己都忘得差不多了,那就大家一起溫習吧(如果内容有錯誤或有疑問,可以來信咨詢:陳朋奕 chenpengyi#gmail.com),國内關于MySQL聯結查詢的資料十分少,相信大家在看了本文後會對MySQL聯結文法有相當清晰的了解,也不會被Oracle的外聯結的(“+”号)弄得糊塗了。
在SQL标準中規劃的(Join)聯結大緻分為下面四種:
1. 内聯結:将兩個表中存在聯結關系的字段符合聯結關系的那些記錄形成記錄集的聯結。
2. 外聯結:分為外左聯結和外右聯結。
左聯結A、B表的意思就是将表A中的全部記錄和表B中聯結的字段與表A的聯結字段符合聯結條件的那些記錄形成的記錄集的聯結,這裡注意的是最後出來的記錄集會包括表A的全部記錄。
右聯結A、B表的結果和左聯結B、A的結果是一樣的,也就是說:
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左聯結B則A中所有記錄都會保留在結果中,此時B中隻有符合聯結條件的記錄,而右聯結相反,這樣也就不會混淆了。其實大家回憶高等教育出版社出版的《資料庫系統概論》書中講到關系代數那章(就是将笛卡兒積和投影那章)的内容,相信不難了解這些聯結功能的内涵。
2. MySQL聯結(Join)的文法
MySQL支援Select和某些Update和Delete情況下的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)
這兩個例子不僅讓我們了解了MySQL中table_factor和table_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的标準寫法,隻是為了和ODBC的SQL文法相容而設定的,我很少用,Java的人更是不會用,是以也不多解釋了。
那下面就具體講講簡單的JOIN的用法了。首先我們假設有2個表A和B,他們的表結構和字段分别為:
表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 | Basketball,Tennis |
John |