右外连接类似于维恩图的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?
答案 0 :(得分:3)
您的查询是
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 JOIN
到orders
的加入条件为partnum=54
,因此orders
时parts
的{{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。