为简单起见,假设所有相关字段都为NOT NULL。

你可以:

SELECT
    table1.this, table2.that, table2.somethingelse
FROM
    table1, table2
WHERE
    table1.foreignkey = table2.primarykey
    AND (some other conditions)

否则:

SELECT
    table1.this, table2.that, table2.somethingelse
FROM
    table1 INNER JOIN table2
    ON table1.foreignkey = table2.primarykey
WHERE
    (some other conditions)

这两者在MySQL中工作方式相同吗?


当前回答

我还将指出,使用旧语法更容易出错。如果使用不带ON子句的内部连接,则会出现语法错误。如果您使用旧的语法并且忘记了where子句中的一个连接条件,那么您将得到一个交叉连接。开发人员通常通过添加不同的关键字来解决这个问题(而不是修复连接,因为他们仍然没有意识到连接本身已经损坏),这可能看起来解决了问题,但会大大降低查询速度。

此外,对于维护,如果您在旧语法中有一个交叉连接,维护者如何知道您是否有意要有一个交叉连接(在需要交叉连接的情况下),或者这是一个应该修复的意外?

让我向您指出这个问题,看看为什么使用左连接时隐式语法不好。 Sybase *= Ansi标准与2个不同的外部表相同的内部表

另外,使用显式连接的标准已经超过20年了,这意味着隐式连接语法在这20年里已经过时了。你会使用已经过时20年的语法来编写应用程序代码吗?为什么要编写数据库代码呢?

其他回答

INNER JOIN是你应该使用的ANSI语法。

它通常被认为更具可读性,特别是当您连接许多表时。

当需要时,还可以轻松地用OUTER JOIN替换它。

WHERE语法更面向关系模型。

两个表连接的结果是应用筛选器的表的笛卡尔积,筛选器只选择连接列匹配的行。

使用WHERE语法更容易看到这一点。

至于你的例子,在MySQL中(通常在SQL中),这两个查询是同义词。

另外,请注意MySQL也有一个STRAIGHT_JOIN子句。

使用这个子句,可以控制JOIN顺序:在外部循环中扫描哪个表,在内部循环中扫描哪个表。

在MySQL中不能使用WHERE语法来控制这一点。

一旦需要向查询中添加更多的表,隐式连接(第一个查询就是隐式连接)将变得更加混乱、难以阅读和维护。想象一下,在四五个不同的表上执行相同的查询和类型的连接……这是一场噩梦。

使用显式连接(第二个示例)可读性更强,也更容易维护。

对于隐式连接,我有两点(第二个例子):

告诉数据库您想要什么,而不是它应该做什么。 您可以在一个清晰的列表中编写所有表,而不受连接条件的影响。这样你就可以更容易地阅读所有提到的表。所有的条件都出现在WHERE部分,它们也都是一个接一个地排列。使用JOIN关键字会混淆表和条件。

如果您经常编写动态存储过程,那么您会爱上第二个示例(使用where)。如果你有各种各样的输入参数和大量的变形混乱,那么这是唯一的方法。否则,它们将运行相同的查询计划,因此在经典查询中肯定没有明显的区别。

我知道你说的是MySQL,但不管怎样: 在Oracle 9中,显式连接和隐式连接将生成不同的执行计划。AFAIK在Oracle 10+中已经解决了:不再有这样的区别了。