1.內聯結、外聯結、左聯結、右聯結的含義及區別:html
在講MySQL的Join語法前仍是先回顧一下聯結的語法,呵呵,其實連我本身都忘得差很少了,那就你們一塊兒溫習吧(若是內容有錯誤或有疑問,能夠來信諮詢:陳朋奕chenpengyi#gmail.com),國內關於MySQL聯結查詢的資料十分少,相信你們在看了本文後會對MySQL聯結語法有至關清晰的瞭解,也不會被Oracle的外聯結的(「+」號)弄得糊塗了。java
在SQL標準中規劃的(Join)聯結大體分爲下面四種:數據庫
1. 內聯結:將兩個表中存在聯結關係的字段符合聯結關係的那些記錄造成記錄集的聯結。優化
2. 外聯結:分爲外左聯結和外右聯結。spa
左聯結A、B表的意思就是將表A中的所有記錄和表B中聯結的字段與表A的聯結字段符合聯結條件的那些記錄造成的記錄集的聯結,這裏注意的是最後出來的記錄集會包括表A的所有記錄。.net
右聯結A、B表的結果和左聯結B、A的結果是同樣的,也就是說:orm
Select A.name B.name From A Left Join B On A.id=B.idhtm
和Select A.name B.name From B Right Join A on B.id=A.id執行後的結果是同樣的。blog
3.全聯結:將兩個表中存在聯結關係的字段的全部記錄取出造成記錄集的聯結(這個不須要記憶,只要是查詢中提到了的表的字段都會取出,不管是否符合聯結條件,所以意義不大)。ci
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 |
|
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聯結查詢中的某些參數的做用:
1.USING (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來代替會書寫比較麻煩而已。
2.NATURAL [LEFT] JOIN:這個句子的做用至關於INNER JOIN,或者是在USING子句中包含了聯結的表中全部字段的Left JOIN(左聯結)。
3.STRAIGHT_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,轉載請註明出處及做者。
轉載自: http://www.blogjava.net/chenpengyi/archive/2005/10/17/15747.html