2012-08-04 223 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相同。如果添加新文章而不添加相关新闻组(反之亦然),则结果也会改变。