【问题标题】:Which is better.. left outer join or right outer join?哪个更好.. 左外连接或右外连接?
【发布时间】:2011-09-09 06:49:44
【问题描述】:

我们可以通过这两种方式得到相同的结果..

Table_1 LEFT OUTER JOIN Table_2

Table_2 RIGHT OUTER JOIN Table_1

如果我们能得到相同的结果,为什么要使用右外连接?哪个更好?

【问题讨论】:

  • 总结ab,你可以做a+bb+a。哪个更好?
  • 我认为现代 RDBMS 可以将一个转换为另一个并选择性能更好的一个,所以这无关紧要。

标签: sql join


【解决方案1】:

正如其他人已经指出的那样,LEFT OUTER JOINRIGHT OUTER JOIN 是完全相同的操作,只是它们的参数相反。你的问题就像问写a < b 还是b > a 更好。它们是相同的 - 只是偏好问题。

话虽如此,我发现大多数人更熟悉LEFT JOIN,并在他们的SQL 中始终如一地使用它。如果在查询中间突然出现RIGHT JOIN,有些人甚至会觉得很难阅读,这会导致他们不得不停下来思考它的含义。所以我建议在这两个选项之间进行平等选择,更喜欢使用LEFT JOIN。保持一致将使其他开发人员更容易理解您的 SQL。

【讨论】:

  • 这是一个比我在 cmets 中添加的一个更好的例子。出于某种原因,我在一个不对称的简单运算符上画了一个空白:-)
  • 是的。我认为对 LEFT 的偏好可能来自于开始使用最“重要”表编写查询的自然倾向,这些表通常包含完整信息,即没有丢失任何行,并添加可能包含或可能不包含相关信息的表那个。
【解决方案2】:

这些都是平等的,只是偏好和可读性的问题。我假设它是相同的表?

【讨论】:

  • +1,我建议您选择一个偏好并坚持下去。如果您在外部连接中保持一致,最终结果应该是相同的。如果您不确定,我还建议您使用左外连接,因为大多数其他人都这样做。
【解决方案3】:

左外连接

表 A 和 B 的左外连接(或简称为左连接)的结果始终包含“左”表 (A) 的所有记录,即使连接条件在“右”表 (B)。这意味着如果 ON 子句匹配 B 中的 0(零)条记录,则连接仍将在结果中返回一行,但 B 中的每一列都为 NULL。这意味着左外连接返回所有值来自左表,加上来自右表的匹配值(如果没有匹配的连接谓词,则为 NULL)

右外连接

右外连接(或右连接)与左外连接非常相似,除了表的处理方式相反“右”表 (B) 中的每一行将至少出现在连接表中一次。 如果“左”表 (A) 中不存在匹配的行,则 NULL 将出现在 A 的列中对于那些在 B 中没有匹配的记录。右外连接返回右表中的所有值和左表中的匹配值(在没有匹配连接谓词的情况下为 NULL)。

http://en.wikipedia.org/wiki/Join_%28SQL%29

【讨论】:

  • 是的,但我认为 OP 提出的问题是 A LEFT OUTER JOIN B 是否与 B RIGHT OUTER JOIN A 相同(注意 tables 也已交换作为连接方向。)
  • 我只是想写出它们是如何工作的,因为这样人们就可以理解,如果像在问题中那样使用它们,它们并没有什么不同,而且它是更有用的信息。
【解决方案4】:

SQL 语言的设计者正确地认为,强制从左到右的连接优先级对语言来说是不必要的限制(遗憾的是,他们对列顺序的感觉不一样!)

在 Stackoverflow 上似乎确实对 LEFT OUTER 有强烈的偏好,以至于人们会更改整个连接以便能够使用 LEFT(我们昨天有一个 here)。

假设您最初在查询Table_2 INNER JOIN Table_1 中编写,然后才意识到您实际上需要一个外连接来保留来自Table_1 的所有行。将INNER 更改为RIGHT OUTER 比将整个连接更改为能够使用LEFT OUTER 要简单得多。简单在这里很好,因为它侵入性较小,因此查询意图被无意更改的风险较小。

要使用另一个类似的示例,请考虑关系运算符semi join;作为关系代数的一部分,没有它,一项技术就不能被认为是关系完整的。尽管标准 SQL 确实有一个半连接谓词 MATCH,但它并未得到广泛实施。但是,大多数 SQL 产品都支持各种变通方法。在 Stackoverflow 上看到的最常见的方法似乎是在 SELECT 子句中使用 INNER JOINDISTINCT 并从连接表中省略属性。紧随其后的是使用WHERE table_1.ID IN (SELECT ID FROM Table_2)。接下来最受欢迎的是WHERE EXISTS (SELECT * FROM Table_2 WHERE table_1.ID = table_1.ID)

关键是,以上都是在野外非常常见的半连接。虽然我个人的偏好是使用EXISTS(虽然奇怪的是它更接近关系演算),但我仍然需要能够将其他人识别为半连接;有趣的是,最流行的方法(INNER JOIN 加上DISTINCT 加上非投影)可能是最难识别的!

仅仅为了适应个人风格而重构代码是不受欢迎的:不必要的努力成本、增加风险、对源代码控制的影响等。学会识别和尊重他人的偏好是一项重要的技能:如果你发现自己重构一次只是为了能够理解它,您将处于不利地位。

当然,相对而言,“正确”的答案是完全避免外连接。关系模型中没有 null 这样的东西,外连接被明确设计为产生 null。

【讨论】:

    【解决方案5】:

    这取决于我们的需要——我们是否需要左表或右表中的所有列。

    两者都不一样。

    【讨论】:

    • 在这两个查询中,我们从 Table_1 中获取所有行。即相同的结果。顺便说一句,它应该是 ..“是否”:)
    猜你喜欢
    • 2014-02-24
    • 2015-01-11
    • 1970-01-01
    • 2020-07-28
    • 2016-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    相关资源
    最近更新 更多