为简单起见,假设所有相关字段都为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中工作方式相同吗?


当前回答

ANSI连接语法肯定更可移植。

我正在进行Microsoft SQL Server的升级,我还会提到,2005年SQL Server及以后的版本不支持外部连接的=*和*=语法(没有兼容模式)。

其他回答

它们有不同的人类可读的含义。

但是,根据查询优化器的不同,它们对于机器可能具有相同的含义。

您应该始终使代码易于阅读。

也就是说,如果这是一个内置关系,则使用显式连接。如果匹配的是弱相关数据,则使用where子句。

ANSI连接语法肯定更可移植。

我正在进行Microsoft SQL Server的升级,我还会提到,2005年SQL Server及以后的版本不支持外部连接的=*和*=语法(没有兼容模式)。

SQL:2003标准更改了一些优先级规则,因此JOIN语句优先于“逗号”连接。这实际上可以改变查询的结果,这取决于它是如何设置的。当MySQL 5.0.12切换到遵循标准时,这对一些人造成了一些问题。

因此,在您的示例中,查询的工作原理是一样的。但是如果你添加第三个表: 选择……从table1, table2 JOIN table3 ON…在那里……

在MySQL 5.0.12之前,table1和table2先被连接,然后是table3。现在(5.0.12之后),table2和table3先被连接,然后是table1。它并不总是会改变结果,但它可以,而且你可能甚至没有意识到。

我不再使用“逗号”语法,选择你的第二个例子。无论如何,它都更具有可读性,JOIN条件是与JOIN一起的,而不是分离到单独的查询部分中。

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

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

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

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

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