【问题标题】:Is the following join sentence valid?下面的连接句是否有效?
【发布时间】: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


【解决方案1】:

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 子句代替连接会更慢,因为更多 行必须连接,对吧?

我真的不明白这个问题。

您可以选择LEFTRIGHT 连接,具体取决于您是要保留来自左侧输入还是右侧输入的所有行。对于简单的 2 表查询,您当然可以使用其中任何一种,只需颠倒表的顺序即可。

对于是否将过滤器放在WHERE 子句或JOIN 条件中的问题也是如此。在OUTER JOIN 中,这可以改变结果(在我的示例中,将b.c = 1 移动到WHERE 子句的数据意味着只返回1 行而不是2)

对于INNER JOIN 的情况,过滤器的放置位置无关紧要,但我发现将过滤器与JOIN 中的两个表之间的关系以及WHERE 中的所有其他表之间的关系放在一起更明智

【讨论】:

  • 那我如何LEFT JOIN 而不添加过滤后的行呢?如果我使用WHERE 子句,则连接会变慢,因为必须连接更多行,对吧?
  • 对不起,我在评论中指的是RIGHT JOIN,但我想我现在明白了。
【解决方案2】:

是的。 on子句中可以有与其他表无关的额外条件

【讨论】:

  • 如果连接是 RIGHT JOIN 怎么办?当我使用 RIGHT JOIN 时, b.c = 1 部分被忽略
【解决方案3】:

是的,它是有效的。

但是,当您使用右连接时,您将有效地获取“右”表中除了满足连接条件的值之外不满足连接条件的所有值。这就是 right join 的作用

在这种情况下,使用 where 子句来限制从表 b 中提取的内容。

从一个 右连接 b 在 a.c = b.c WHERE b.c = 1

【讨论】:

    【解决方案4】:

    为什么不写成这样更清楚:

    FROM a
    JOIN b on a.c = b.c
    WHERE b.c = 1
    

    【讨论】:

    • 你应该把你所有的条件放在join子句的表“b”上
    • 雷米 - 为什么?是否应该在 ON 或 WHERE 子句中放置条件取决于它是否与连接操作的逻辑或整体查询的逻辑有关。
    • @Hammerite - 我认为 remi 正在考虑 RIGHT JOIN 案例,但它看起来好像是作为附加问题附加的,并且最初并不存在。
    猜你喜欢
    • 1970-01-01
    • 2013-10-29
    • 2019-02-14
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    • 2011-10-14
    • 1970-01-01
    相关资源
    最近更新 更多