【问题标题】:SQL join condition A=B or reverse to B=A?SQL 连接条件 A=B 或反转为 B=A?
【发布时间】:2009-05-15 14:52:53
【问题描述】:

我认为这对数据库没有任何影响,但是在连接表时,您更喜欢哪种顺序来编写条件:

SELECT
    ...
    FROM AAA
        INNER JOIN BBB ON AAA.ID=BBB.ID
    WHERE ...

SELECT
    ...
    FROM AAA
        INNER JOIN BBB ON BBB.ID=AAA.ID
    WHERE ...

【问题讨论】:

  • 还有就是把这个扔在这里...... SELECT * FROM AAA, BBB WHERE AAA.ID = BBB.ID 怎么样
  • T Pops 我不建议任何人使用这种语法。它已经过时了 17 年,而且更容易出错(意外交叉连接)并且更难理解和维护。
  • 如果不使用实际的连接子句,也无法进行某些复杂的连接
  • 有趣。只有两个选项,已经有十个答案了。
  • 我发现有趣的是,在许多人解释了他们为什么选择每种方式之后,选择的“正确”答案只是一个简单的“我选择 A”。如果 OP 知道他想从什么开始,那么问题的意义何在?

标签: sql join


【解决方案1】:

我更喜欢第二个示例 (B=A),因为在连接中我列出了确定应包含哪些 B 行的条件。换句话说,我想要 B 中的所有行,其中“X”对 B 是正确的。当我需要检查除 FK 之外的标准时,这也是一致的。例如:

SELECT
     some_columns
FROM
     Table_A A
INNER JOIN Table_B B ON
     B.a_id = A.a_id AND
     B.active = 1

在我看来,如果我有,它就不会具有相同的可读性:

1 = B.active

还要考虑您的联接条件包括多个表的情况:

SELECT
     some_columns
FROM
     Table_A A
INNER JOIN Table_B B ON
     B.a_id = A.a_id AND
     B.active = 1
INNER JOIN Table_C C ON
     C.a_id = A.a_id AND
     C.b_id = B.b_id AND
     C.category = 'Widgets'

对我来说,这使得 C 中的行应包含的标准非常清楚。

【讨论】:

  • 这正是我更喜欢 B=A 格式的原因,我觉得我在“解释”如何包含 B。
  • Tom 比我在回答中更好地说明了偏好的理由。基本上,对后一种模式的偏好出现在更复杂的连接中,当连接多个表、内联视图、多个谓词时。对于更简单的情况也遵循相同的模式,就像原始问题中的示例一样,使用一个谓词连接两个表。
  • 我之前并没有真正考虑过,但现在这里建议我想我会改变我的方式。 +1 以获得很好的解释和清晰的代码示例。
【解决方案2】:

我更喜欢第二个选项,即最近写入的表格排在最前面。

不过,我认为 Linq 要求它是相反的(选项 1)。

【讨论】:

  • @Michael Haren,我更喜欢 A=B,但你不是唯一的。我问这个问题是想看看我是不是疯了,和我一起工作的很多人都使用 B=A!
  • +1 你不是唯一一个。是的,LINQ 需要第二种格式。
【解决方案3】:

我总是这样

From TABLE_A A

JOIN TABLE_B B ON A.Column = B.Column

【讨论】:

    【解决方案4】:

    没关系,两者都是正确的。我更喜欢第二种。

    我的偏好是基于表 BBB 是我要添加到结果集中的表的想法,而手头的工作是将新表 BBB 中的列(表达式)绑定到结果集中已经存在的其他列。在不同的例子中可能更有意义:

    SELECT ...
      FROM AAA a
      JOIN BBB b ON (b.AAA_ID = a.ID)
      JOIN CC c ON (c.AAA_ID = b.AAA_ID AND UPPER(c.FEE) IN ('FI','FO'))
      JOIN DDD d ON (d.CC_ID = c.ID AND LEFT(d.DAH,2) = c.FEE)
    

    是的,这是一个任意复杂的示例,但有时实际代码确实会变得如此复杂。在连接条件中引用多个谓词时,我发现每个谓词引用最近连接的表中的第一个(左侧)表达式时很有帮助。

    还有其他模式也有帮助,例如,当每个表的主键是名为“ID”的单个列而外键列通常命名为 PARENTTABLE_ID 时,这样当我看到像 a.ID 这样的构造时=b.ID,我看到的是主键连接到主键的模式(一对一的关系,这不是规范模式)。当我看到 b.FOREIGN_ID = c.FOREIGN_ID 时,我看到的是外键连接到外键。同样,不是通常的模式,表明这可能是多对多连接,或者可能是性能的快捷连接。我在父子连接中寻找的通常模式是 child.PARENT_ID = parent.ID

    这些模式没有对错之分,只是一种偏好。我发现这些模式不会让正确的代码看起来很漂亮,但会让“奇怪”的代码脱颖而出。

    【讨论】:

    • Tom H. 解释它比我做得更好,我同意他的回答,原因是他给出的。如果只是简单的情况,那没关系。该偏好基于遵循我们认为对更复杂案例有帮助的相同模式。
    • +1 参考了 Tom H 的答案,如果没有你的笔记,我可能不会读到它。
    【解决方案5】:

    我更喜欢第一个选项。您要从 A 到 B,因此字段的顺序似乎更合适。

    【讨论】:

      【解决方案6】:

      我不认为它真的有什么不同,但我更喜欢

      INNER JOIN BBB ON AAA.ID=BBB.ID
      

      因为和linq一致。

      【讨论】:

        【解决方案7】:

        AAA.ID = BBB.ID 的另一个温和声音。这对我来说似乎更有意义,但这并不重要。

        然而,在一个切线相关的注释中,我最近开始质疑我是如何编写相等测试的。我一直喜欢:

        If ValueInQuestion = TestValue Then
        ...
        

        也就是说,

        If fullMoonsThisMonth = 2 Then
        ...
        

        在其他人的代码中,我经常看到这个测试被颠倒了,这让我困扰了一段时间。我开始意识到我的偏好是基于在英语中哪个表述听起来“更好”,并且有时将不变值放在左边是有充分理由的。在只有一个运算符用于相等性测试和赋值的语言中(例如 VB,以防您不认识示例......),然后编译器将阻止您在您打算进行测试时意外地进行赋值。

        【讨论】:

          【解决方案8】:

          没有区别,但为了清楚起见,我会选择“AAA INNER JOIN BBB ON AAA.ID=BBB.ID”(但有别名)

          【讨论】:

            【解决方案9】:

            我使用第一个语法 AAA.ID = BBB.ID。在我看来,它使代码更易于阅读,因为加入参与者遵循表格顺序。

            【讨论】:

              【解决方案10】:

              我倾向于同时使用两者,因为它根本没有区别。

              【讨论】:

                【解决方案11】:

                只要查询中已经提到了您引用的表,您编写联接的顺序无关紧要。

                我个人更喜欢将最近的表列在第二位(选项 1)。这种约定很有帮助,因为我决定在需要时始终使用 LEFT OUTER JOIN(而不是 RIGHT OUTER JOIN),而且我不必考虑哪个表将在右侧或左侧。

                【讨论】:

                • 你的回答让我有点困惑。 FROM 子句中表的顺序(以及您想要的结果集)决定了外连接是指定为 LEFT 还是 RIGHT。连接谓词中的表达式顺序与外连接无关。
                【解决方案12】:

                让我们在这里记住 LINQ 不是 SQL,那么为什么还要在这里提到它呢? SQL 问题不应该用 LINQ 答案来回答。在我看来,这很奇怪而且完全不相关!

                这两个例子都是可以接受的。正如大多数 SQL 开发人员一样,我更喜欢第二个示例。它还取决于您要使用的 SQL JOIN 类型。问题标题仅适用于“JOIN”,但您的示例使用了 INNER JOIN。

                在这种情况下,对于 INNER JOIN,这无关紧要。但请记住,这两个示例都会产生 HASH MATCHED JOIN,这在处理索引时并不理想。 循环连接效率更高。只需确保将索引视为哈希联接是索引效率低下的指标。

                【讨论】:

                  【解决方案13】:

                  根据两个表的索引方式以及它们连接的字段是否会产生性能差异?

                  无论您指定什么顺序,某些数据库引擎中的查询优化器可能都能做正确的事情,但只有在查询计划和测试的一段时间内才能确定答案。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2014-03-29
                    • 2021-10-06
                    • 2015-06-10
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2021-11-28
                    • 1970-01-01
                    相关资源
                    最近更新 更多