在MySQL查询中,为什么使用join而不是where?

在MySQL查询中,为什么使用join而不是where?,sql,mysql,database,Sql,Mysql,Database,似乎要组合两个或多个表,我们可以使用join或where。一个连接比另一个连接有什么优点?显式连接传递意图,留下where子句进行过滤。它更干净,而且是标准的,您可以做一些事情,例如左外或右外,这仅在where中很难做到。大多数人倾向于发现JOIN语法更清楚地说明什么是连接到什么。此外,它还具有作为标准的优点 就我个人而言,我是在何处“长大”的,但我越是使用JOIN语法,我就越开始意识到它是多么的清晰。你不能使用WHERE来组合两个表。但你可以做的是写: SELECT * FROM A, B W

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

显式连接传递意图,留下where子句进行过滤。它更干净,而且是标准的,您可以做一些事情,例如左外或右外,这仅在where中很难做到。

大多数人倾向于发现JOIN语法更清楚地说明什么是连接到什么。此外,它还具有作为标准的优点


就我个人而言,我是在何处“长大”的,但我越是使用JOIN语法,我就越开始意识到它是多么的清晰。

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

SELECT * FROM A, B
WHERE ...
这里的逗号相当于写:

SELECT *
FROM A
CROSS JOIN B
WHERE ...

你会写吗?不,因为这根本不是你的意思。你不需要交叉连接,你需要内部连接。但是当你写逗号时,你说的是交叉连接,这很混乱。

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

  • 在FROM子句中以逗号分隔的列表列出所涉及的表
  • 在WHERE子句中写入表之间的关联

    SELECT *
      FROM TABLE_A a,
           TABLE_B b
     WHERE a.id = b.id
    
  • 以下是使用ANSI-92连接语法重新编写的查询:

    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语法中获益:

    • 能够控制连接顺序-扫描表的顺序
    • 能够在加入前对表应用筛选条件
    从维护的角度来看:
    与ANSI-89相比,使用ANSI-92联接语法有许多原因:

    • 更具可读性,因为连接条件与WHERE子句是分开的
    • 不太可能错过加入条件
    • 对内部以外的联接类型提供一致的语法支持,使查询易于在其他数据库上使用
    • WHERE子句仅用于过滤所联接表的笛卡尔积
    从设计角度来看:
    ANSI-92连接语法是模式,而不是反模式:

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

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

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

    首先,由于连接条件不在表名旁边,因此很容易发生意外的交叉连接。如果有6个表连接在一起,很容易在where子句中遗漏一个表。通过使用distinct关键字,您将经常看到此问题已得到修复。这对数据库来说是一个巨大的性能打击。使用显式连接语法无法获得意外交叉连接,因为它将无法通过语法检查

    在某些数据库中,使用旧语法时,右连接和左连接是有问题的(在SQl server中,不能保证获得正确的结果)。此外,据我所知,它们在SQL Server中已被弃用

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

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

    我还注意到,一些使用这些隐式连接的人实际上并不了解连接是如何工作的,因此在他们的查询中得到了错误的结果


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

    实际上,您经常需要“WHERE”和“JOIN”。

    “JOIN”用于根据公共列的值从两个表中检索数据。如果要进一步筛选此结果,请使用WHERE子句


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

    根据您的使用情况,它可能具有相同的结果,但使用JOIN可以进行其他类型的关联。这是否回答了您的问题?“…任何涉及多个表的查询都需要某种形式的关联,以将表‘A’的结果链接到表‘B’……否则,您将得到笛卡尔乘积,您可能不希望这样(那些笛卡尔乘积很糟糕)@nawfal我明白-我从小就学习旧式语法,但一旦我习惯了新语法,好处就变得很明显了,例如更难错误地进行交叉连接,更明确,更容易看到什么是连接,什么是过滤器,等等……我上瘾了。