不确定这个右外连接的结果是什么

时间:2013-02-15 09:53:15

标签: mysql sql join outer-join

右外连接类似于维恩图的Union对吗? 我的意思是A right outer Join B我们应该获得B的所有行以及A中的所有匹配行。
出于某种原因,我对以下内容感到困惑:
假设表Orders

mysql> select * from orders;  
+------------+------------+---------+----------+---------+  
| orderedon  | name       | partnum | quantity | remarks |  
+------------+------------+---------+----------+---------+  
| 1996-05-19 | TRUE-WHEEL |      76 |        3 | PAID    |  
| 1996-09-02 | TRUE-WHEEL |      10 |        1 | PAID    |   
| 1996-06-30 | TRUE-WHEEL |      42 |        8 | PAID    |   
| 1996-06-30 | BIKE SPEC  |      54 |       10 | PAID    |  
| 1996-05-30 | BIKE SPEC  |      23 |        8 | PAID    |   
| 1996-01-17 | BIKE SPEC  |      76 |       11 | PAID    |  
| 1996-01-17 | LE SHOPPE  |      76 |        5 | PAID    |  
| 1996-06-01 | LE SHOPPE  |      10 |        3 | PAID    |  
| 1996-06-01 | AAA BIKE   |      10 |        1 | PAID    |   
| 1996-07-01 | AAA BIKE   |      76 |        4 | PAID    |  
| 1996-07-01 | AAA BIKE   |      46 |       14 | PAID    |   
| 1996-07-11 | JACKS BIKE |      76 |       14 | PAID    |  
| 1996-05-15 | TRUE-WHEEL |      23 |        6 | PAID    |  
| 1996-05-30 | BIKE SPEC  |      20 |        2 | PAID    |   
+------------+------------+---------+----------+---------+   
14 rows in set (0.00 sec)

和表格Part

mysql> select * from part;  
+---------+---------------+---------+  
| partnum | description   | price   |  
+---------+---------------+---------+  
|      54 | PEDALS        |   54.25 |  
|      42 | SEATS         |   24.50 |  
|      46 | TIRES         |   15.25 |  
|      23 | MOUNTAIN BIKE |  350.45 |  
|      76 | ROAD BIKE     |  530.00 |  
|      10 | TANDEM        | 1200.00 |  
+---------+---------------+---------+  
6 rows in set (0.00 sec)  

我期待以下查询:
select p.partnum p_partnum,p.description p_desc,p.price p_price,o.name o_name,o.partnum o_partnum from part p right outer join orders o on o.partnum=54;
会给我Orders的所有行以及part的{​​{1}}行。 但我明白了:

partnum=54

为什么我会获得额外的行?为什么它将mysql> select p.partnum p_partnum,p.description p_desc,p.price p_price,o.name o_name,o.partnum o_partnum from part p right outer join orders o on o.partnum=54; +-----------+---------------+---------+------------+-----------+ | p_partnum | p_desc | p_price | o_name | o_partnum | +-----------+---------------+---------+------------+-----------+ | NULL | NULL | NULL | TRUE-WHEEL | 76 | | NULL | NULL | NULL | TRUE-WHEEL | 10 | | NULL | NULL | NULL | TRUE-WHEEL | 42 | | 54 | PEDALS | 54.25 | BIKE SPEC | 54 | | 42 | SEATS | 24.50 | BIKE SPEC | 54 | | 46 | TIRES | 15.25 | BIKE SPEC | 54 | | 23 | MOUNTAIN BIKE | 350.45 | BIKE SPEC | 54 | | 76 | ROAD BIKE | 530.00 | BIKE SPEC | 54 | | 10 | TANDEM | 1200.00 | BIKE SPEC | 54 | | NULL | NULL | NULL | BIKE SPEC | 23 | | NULL | NULL | NULL | BIKE SPEC | 76 | | NULL | NULL | NULL | LE SHOPPE | 76 | | NULL | NULL | NULL | LE SHOPPE | 10 | | NULL | NULL | NULL | AAA BIKE | 10 | | NULL | NULL | NULL | AAA BIKE | 76 | | NULL | NULL | NULL | AAA BIKE | 46 | | NULL | NULL | NULL | JACKS BIKE | 76 | | NULL | NULL | NULL | TRUE-WHEEL | 23 | | NULL | NULL | NULL | BIKE SPEC | 20 | +-----------+---------------+---------+------------+-----------+ 19 rows in set (0.00 sec) 行与Order的行合并到`part?

的所有行

4 个答案:

答案 0 :(得分:3)

enter image description here

您的查询是

select p.partnum p_partnum,p.description p_desc,p.price p_price,o.name   o_name,o.partnum o_partnum 
from part p right outer join orders o on o.partnum=54;  

您要进行正确加入,所以即使右侧的加入表中没有匹配项,它也会显示记录,并且在这种情况下会发生您的查询

同样适用于左连接,即使它们不匹配,也会显示左侧表格的所有记录

参考http://www.w3schools.com/sql/sql_join_right.asp

详细解释

希望这有帮助

答案 1 :(得分:1)

由于您RIGHT JOINorders的加入条件为partnum=54,因此ordersparts的{​​{1}}加入了所有行。您有一行partnum=54,该行与partnum=54的所有行(交叉联接)相连接。

答案 2 :(得分:1)

FROM part p 
RIGHT OUTER JOIN orders o 
  ON o.partnum=54

...只有订单条件,你需要添加的条件是零件也对应订单,或者数据库会认为任何零件匹配;

FROM part p 
RIGHT OUTER JOIN orders o 
  ON o.partnum=54
 AND o.partnum = p.partnum

当然,如果您只想显示partnum = 54的行,则最好将o.partnum=54移至WHERE条件。 JOIN条件通常用于连接表,WHERE通常用于过滤。

答案 3 :(得分:1)

您在o.partnum = 54上使用ON condition,这就是您获得额外行的原因 在你的结果中。

您需要将条件o.partnum = 54放在where子句上。

这个怎么样

select p.partnum p_partnum,p.description p_desc,p.price p_price,o.name o_name,o.partnum  o_partnum 
from part p right outer join orders o 
on o.partnum = p.partnum
where o.partnum=54;

编辑:您可以参考此beautiful article结果集如何受到干扰 把条件放在ON子句和Where。