2012-08-04 268 views
2

在這種情況下,左連接與右連接相同?右連接與左連接

mysql> 
mysql> 
mysql> use usenet;show tables;describe ARTICLE;describe NEWSGROUP; 
Database changed 
+------------------+ 
| Tables_in_usenet | 
+------------------+ 
| ARTICLE   | 
| NEWSGROUP  | 
+------------------+ 
2 rows in set (0.00 sec) 

+---------------+------------+------+-----+---------+----------------+ 
| Field   | Type  | Null | Key | Default | Extra   | 
+---------------+------------+------+-----+---------+----------------+ 
| ID   | bigint(20) | NO | PRI | NULL | auto_increment | 
| MESSAGENUMBER | int(11) | YES |  | NULL |    | 
| NEWSGROUP_ID | bigint(20) | YES | MUL | NULL |    | 
+---------------+------------+------+-----+---------+----------------+ 
3 rows in set (0.01 sec) 

+-----------+--------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+-----------+--------------+------+-----+---------+----------------+ 
| ID  | bigint(20) | NO | PRI | NULL | auto_increment | 
| NEWSGROUP | varchar(255) | YES |  | NULL |    | 
+-----------+--------------+------+-----+---------+----------------+ 
2 rows in set (0.00 sec) 

mysql> 
mysql> select * from ARTICLE right join NEWSGROUP on ARTICLE.NEWSGROUP_ID=NEWSGROUP.ID; 
+------+---------------+--------------+----+-------------------------------+ 
| ID | MESSAGENUMBER | NEWSGROUP_ID | ID | NEWSGROUP      | 
+------+---------------+--------------+----+-------------------------------+ 
| 1 |    4 |   1 | 1 | gwene.com.androidcentral  | 
| 2 |    5 |   1 | 1 | gwene.com.androidcentral  | 
| 3 |    6 |   1 | 1 | gwene.com.androidcentral  | 
| 4 |    7 |   1 | 1 | gwene.com.androidcentral  | 
| 5 |    8 |   1 | 1 | gwene.com.androidcentral  | 
| 6 |    9 |   1 | 1 | gwene.com.androidcentral  | 
| 7 |   10 |   1 | 1 | gwene.com.androidcentral  | 
| 8 |   11 |   1 | 1 | gwene.com.androidcentral  | 
| 9 |    4 |   2 | 2 | gwene.com.blogspot.emacsworld | 
| 10 |    4 |   3 | 3 | gwene.com.blogspot.googlecode | 
| 11 |    5 |   3 | 3 | gwene.com.blogspot.googlecode | 
| 12 |    6 |   3 | 3 | gwene.com.blogspot.googlecode | 
| 13 |    7 |   3 | 3 | gwene.com.blogspot.googlecode | 
| 14 |    8 |   3 | 3 | gwene.com.blogspot.googlecode | 
| 15 |    9 |   3 | 3 | gwene.com.blogspot.googlecode | 
| 16 |   10 |   3 | 3 | gwene.com.blogspot.googlecode | 
| 17 |   11 |   3 | 3 | gwene.com.blogspot.googlecode | 
| 18 |    4 |   4 | 4 | gwene.com.economist   | 
| 19 |    5 |   4 | 4 | gwene.com.economist   | 
| 20 |    6 |   4 | 4 | gwene.com.economist   | 
| 21 |    7 |   4 | 4 | gwene.com.economist   | 
| 22 |    8 |   4 | 4 | gwene.com.economist   | 
| 23 |    9 |   4 | 4 | gwene.com.economist   | 
| 24 |   10 |   4 | 4 | gwene.com.economist   | 
| 25 |   11 |   4 | 4 | gwene.com.economist   | 
+------+---------------+--------------+----+-------------------------------+ 
25 rows in set (0.00 sec) 

mysql> 
mysql> select * from ARTICLE left join NEWSGROUP on ARTICLE.NEWSGROUP_ID=NEWSGROUP.ID; 
+----+---------------+--------------+------+-------------------------------+ 
| ID | MESSAGENUMBER | NEWSGROUP_ID | ID | NEWSGROUP      | 
+----+---------------+--------------+------+-------------------------------+ 
| 1 |    4 |   1 | 1 | gwene.com.androidcentral  | 
| 2 |    5 |   1 | 1 | gwene.com.androidcentral  | 
| 3 |    6 |   1 | 1 | gwene.com.androidcentral  | 
| 4 |    7 |   1 | 1 | gwene.com.androidcentral  | 
| 5 |    8 |   1 | 1 | gwene.com.androidcentral  | 
| 6 |    9 |   1 | 1 | gwene.com.androidcentral  | 
| 7 |   10 |   1 | 1 | gwene.com.androidcentral  | 
| 8 |   11 |   1 | 1 | gwene.com.androidcentral  | 
| 9 |    4 |   2 | 2 | gwene.com.blogspot.emacsworld | 
| 10 |    4 |   3 | 3 | gwene.com.blogspot.googlecode | 
| 11 |    5 |   3 | 3 | gwene.com.blogspot.googlecode | 
| 12 |    6 |   3 | 3 | gwene.com.blogspot.googlecode | 
| 13 |    7 |   3 | 3 | gwene.com.blogspot.googlecode | 
| 14 |    8 |   3 | 3 | gwene.com.blogspot.googlecode | 
| 15 |    9 |   3 | 3 | gwene.com.blogspot.googlecode | 
| 16 |   10 |   3 | 3 | gwene.com.blogspot.googlecode | 
| 17 |   11 |   3 | 3 | gwene.com.blogspot.googlecode | 
| 18 |    4 |   4 | 4 | gwene.com.economist   | 
| 19 |    5 |   4 | 4 | gwene.com.economist   | 
| 20 |    6 |   4 | 4 | gwene.com.economist   | 
| 21 |    7 |   4 | 4 | gwene.com.economist   | 
| 22 |    8 |   4 | 4 | gwene.com.economist   | 
| 23 |    9 |   4 | 4 | gwene.com.economist   | 
| 24 |   10 |   4 | 4 | gwene.com.economist   | 
| 25 |   11 |   4 | 4 | gwene.com.economist   | 
+----+---------------+--------------+------+-------------------------------+ 
25 rows in set (0.00 sec) 

mysql> 
mysql> 
+1

[SQL的可視說明聯接](http://www.codinghorror.com/blog/ 2007/10/A-視覺解釋-的-SQL joins.html)。 – eggyal 2012-08-04 08:57:41

+0

這意味着值(NEWSGROUP.ID)=值(ARTICLE.NEWSGROUP_ID) – 2012-08-04 09:08:02

+0

我想爲您描述SQL連接 – 2015-05-14 08:34:23

回答

1

與您目前的數據,是的,他們是一樣的。然而,由於NEWSGROUP_ID是可以爲空的,那麼隨着數據變化它們可能會不同。

就個人而言,如果可能的話,我總是使用LEFT JOIN(從主表到子表),實際上我只需要在6年的SQL開發中使用RIGHT JOIN幾次!

4

不是真的,因爲RIGHT JOIN和LEFT JOIN是對稱的。那就是:

A LEFT JOIN B = B RIGHT JOIN A 

RIGHT JOIN僅僅是語法糖。優化器可以改寫右連接至左連接:

mysql> explain extended select * from t right join t t2 using (c1)\G 
*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: t2 
     type: index 
possible_keys: NULL 
      key: c2 
     key_len: 5 
      ref: NULL 
     rows: 4201 
    filtered: 100.00 
     Extra: Using index 
*************************** 2. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: t 
     type: eq_ref 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 4 
      ref: test.t2.c1 
     rows: 1 
    filtered: 100.00 
     Extra: 
2 rows in set, 1 warning (0.00 sec) 

注意留在優化重寫JOIN(表被交換):

mysql> show warnings\G 
*************************** 1. row *************************** 
    Level: Note 
    Code: 1003 
Message: select `test`.`t2`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2`,`test`.`t`.`c2` AS 
`c2` from `test`.`t` `t2` left join `test`.`t` on((`test`.`t`.`c1` = `test`.`t2`.`c1`)) where 1 
1 row in set (0.00 sec) 

注意(A RIGHT JOIN B !=左連接B)除非(A INNER JOIN B = A LEFT JOIN B)。這是因爲右連接B與左連接B不對稱(它與B左連接A對稱)。

在您的情況下,除非您要加入的列中有NULL值,否則,右連接B將與左連接B相同。如果有NULL值,那麼A LEFT JOIN B不會與A RIGHT JOIN B相同。如果添加新文章而不添加相關新聞組(反之亦然),則結果也會改變。