【问题标题】:In MySQL queries, why use join instead of where?在 MySQL 查询中,为什么使用 join 而不是 where?
【发布时间】:2011-01-15 13:36:02
【问题描述】:

似乎要合并两个或多个表,我们可以使用 join 或 where。一个比另一个有什么优势?

【问题讨论】:

  • 根据您的使用情况,它可能具有相同的结果,但使用 JOIN 您可以进行其他类型的关联。
  • 这能回答你的问题吗? INNER JOIN ON vs WHERE clause

标签: sql mysql database


【解决方案1】:

显式连接传达意图,让 where 子句进行过滤。它更干净,它是标准的,你可以做一些事情,比如左外或右外,这只是在哪里更难做到。

【讨论】:

    【解决方案2】:

    大多数人倾向于发现 JOIN 语法更清楚地表明了什么是与什么相连接的。此外,它还具有成为标准的好处。

    就我个人而言,我是在 WHERE 上“长大”的,但是我使用 JOIN 语法的次数越多,我就越开始明白它是如何变得更加清晰的。

    【讨论】:

    • @nawfal 我理解 - 我是在旧式语法中长大的,但是一旦我习惯了新语法,好处就变得很明显,例如更难错误地进行交叉连接,更明确,更容易看到什么是连接,什么是过滤器等...我上瘾了。
    【解决方案3】:

    您不能使用 WHERE 来组合两个表。你可以做的是写:

    SELECT * FROM A, B
    WHERE ...
    

    这里的逗号相当于写:

    SELECT *
    FROM A
    CROSS JOIN B
    WHERE ...
    

    你会写吗?不——因为这根本不是你的意思。你不想要一个交叉连接,你想要一个内部连接。但是当你写逗号时,你说的是 CROSS JOIN,这很令人困惑。

    【讨论】:

      【解决方案4】:

      任何涉及多个表的查询都需要某种形式的关联来将表“A”的结果链接到表“B”。执行此操作的传统 (ANSI-89) 方法是:

      1. 在 FROM 子句中以逗号分隔的列表列出涉及的表
      2. 在WHERE子句中写表之间的关联

        SELECT *
          FROM TABLE_A a,
               TABLE_B b
         WHERE a.id = b.id
        

      这是使用 ANSI-92 JOIN 语法重写的查询:

      SELECT *
        FROM TABLE_A a
        JOIN TABLE_B b ON b.id = a.id
      

      从性能角度:


      在受支持的情况下(Oracle 9i+、PostgreSQL 7.2+、MySQL 3.23+、SQL Server 2000+),使用任何一种语法都没有性能优势。优化器将它们视为相同的查询。但是更复杂的查询可以从使用 ANSI-92 语法中受益:

      • 能够控制 JOIN 顺序 - 扫描表的顺序
      • 能够在加入之前对表应用过滤条件

      从维护的角度来看:


      使用 ANSI-92 JOIN 语法而不是 ANSI-89 的原因有很多:

      • 更具可读性,因为 JOIN 条件与 WHERE 子句是分开的
      • 不太可能错过 JOIN 条件
      • 对除 INNER 之外的 JOIN 类型提供一致的语法支持,使查询在其他数据库上易于使用
      • WHERE 子句仅用于过滤加入的表的笛卡尔积

      从设计角度:


      ANSI-92 JOIN 语法是模式,而不是反模式:

      • 查询的目的更加明显;应用程序使用的列清晰
      • 它遵循关于尽可能使用严​​格类型的模块化规则。显式几乎普遍更好。

      结论


      缺乏熟悉和/或舒适,我认为继续使用 ANSI-89 WHERE 子句而不是 ANSI-92 JOIN 语法没有任何好处。有些人可能会抱怨 ANSI-92 语法更冗长,但这正是它明确的原因。越明确,就越容易理解和维护。

      【讨论】:

      • "...任何涉及多个表的查询都需要某种形式的关联才能将表“A”的结果链接到表“B”...否则您将获得笛卡尔积,你可能不希望那样(那些笛卡尔制造糟糕的产品)。
      【解决方案5】:

      这些是使用 where 语法(也称为隐式连接)的问题:

      首先,很容易意外交叉连接,因为连接条件不在表名旁边。如果将 6 个表连接在一起,则很容易在 where 子句中遗漏一个。通过使用 distinct 关键字,您会经常看到此问题已得到解决。这对数据库来说是巨大的性能损失。您不能使用显式连接语法意外交叉连接,因为它会导致语法检查失败。

      在某些数据库的旧语法中,右连接和左连接存在问题(在 SQl 服务器中,您不能保证获得正确的结果)。此外,它们在我知道的 SQL Server 中已被弃用。

      如果您打算使用交叉连接,旧语法中并不清楚。使用当前的ANSII标准很清楚。

      对于维护者来说,使用隐式语法准确地查看哪些字段是连接的一部分,甚至哪些表以什么顺序连接在一起要困难得多。这意味着修改查询可能需要更多时间。我认识的人很少,一旦他们花时间对显式连接语法感到满意,就会回到旧的方式。

      我还注意到,一些使用这些隐式连接的人实际上并不了解连接的工作原理,因此在他们的查询中得到了不正确的结果。

      老实说,您会使用 18 年前被更好方法取代的任何其他类型的代码吗?

      【讨论】:

        【解决方案6】:

        其实你经常需要“WHERE”和“JOIN”。

        “JOIN”用于从两个表中检索数据 - 基于公共列的值。如果您想进一步过滤此结果,请使用 WHERE 子句。

        例如,“LEFT JOIN”检索左表中的所有行,以及右表中的匹配行。但这不会过滤任何特定值或不属于 JOIN 的其他列的记录。因此,如果您想进一步过滤此结果,请在 WHERE 子句中指定额外的过滤器。

        【讨论】:

          猜你喜欢
          • 2013-07-25
          • 1970-01-01
          • 2010-12-09
          • 2010-11-17
          • 1970-01-01
          • 2014-09-04
          • 2023-03-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多