【发布时间】:2011-09-06 07:33:36
【问题描述】:
此连接在 MySQL 中是否有效:
FROM a
JOIN b on a.c = b.c and b.c = 1
它确实像这样工作,但是当我使用 RIGHT JOIN 时,b.c = 1 会被忽略。 这是为什么呢?
【问题讨论】:
-
为什么不试试看会发生什么?
标签: mysql sql join outer-join
此连接在 MySQL 中是否有效:
FROM a
JOIN b on a.c = b.c and b.c = 1
它确实像这样工作,但是当我使用 RIGHT JOIN 时,b.c = 1 会被忽略。 这是为什么呢?
【问题讨论】:
标签: mysql sql join outer-join
RIGHT JOIN 不会忽略它。
(从概念上讲)连接发生在应用过滤器的情况下,然后 b 中的任何不匹配行都将重新添加。
所以查询
SELECT a.c, b.c
FROM (select 1 AS c
UNION ALL
SELECT 2) a
RIGHT JOIN (select 1 AS c
UNION ALL
select 2 AS c) b
on a.c = b.c
and b.c = 1
返回
c c
----------- -----------
1 1
NULL 2
您可以看到,尽管两个表都有2,但join 子句中的附加过滤器意味着这些行不会被连接。但是,由于它是 right outer 加入右侧表 (b) 中的 2 行,结果中仍然出现。
编辑:RE:cmets 中的问题
那么我如何
LEFT JOIN而不添加过滤后的行呢?如果 我使用WHERE子句代替连接会更慢,因为更多 行必须连接,对吧?
我真的不明白这个问题。
您可以选择LEFT 与RIGHT 连接,具体取决于您是要保留来自左侧输入还是右侧输入的所有行。对于简单的 2 表查询,您当然可以使用其中任何一种,只需颠倒表的顺序即可。
对于是否将过滤器放在WHERE 子句或JOIN 条件中的问题也是如此。在OUTER JOIN 中,这可以改变结果(在我的示例中,将b.c = 1 移动到WHERE 子句的数据意味着只返回1 行而不是2)
对于INNER JOIN 的情况,过滤器的放置位置无关紧要,但我发现将过滤器与JOIN 中的两个表之间的关系以及WHERE 中的所有其他表之间的关系放在一起更明智
【讨论】:
LEFT JOIN 而不添加过滤后的行呢?如果我使用WHERE 子句,则连接会变慢,因为必须连接更多行,对吧?
RIGHT JOIN,但我想我现在明白了。
是的。 on子句中可以有与其他表无关的额外条件
【讨论】:
是的,它是有效的。
但是,当您使用右连接时,您将有效地获取“右”表中除了满足连接条件的值之外不满足连接条件的所有值。这就是 right join 的作用
在这种情况下,使用 where 子句来限制从表 b 中提取的内容。
从一个 右连接 b 在 a.c = b.c WHERE b.c = 1
【讨论】:
为什么不写成这样更清楚:
FROM a
JOIN b on a.c = b.c
WHERE b.c = 1
【讨论】:
RIGHT JOIN 案例,但它看起来好像是作为附加问题附加的,并且最初并不存在。