为简单起见,假设所有相关字段都为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年的语法来编写应用程序代码吗?为什么要编写数据库代码呢?
隐式联接ANSI语法较旧,不太明显,不推荐使用。
此外,关系代数允许WHERE子句和INNER JOIN中的谓词互换性,因此即使使用WHERE子句的INNER JOIN查询也可以由优化器重新排列谓词。
我建议您以最易读的方式编写查询。
有时,这包括使INNER JOIN相对“不完整”,并将一些标准放在WHERE中,只是为了使过滤条件列表更容易维护。
例如,不要:
SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
ON ca.CustomerID = c.CustomerID
AND c.State = 'NY'
INNER JOIN Accounts a
ON ca.AccountID = a.AccountID
AND a.Status = 1
写:
SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
ON ca.CustomerID = c.CustomerID
INNER JOIN Accounts a
ON ca.AccountID = a.AccountID
WHERE c.State = 'NY'
AND a.Status = 1
当然,这要视情况而定。
INNER JOIN是你应该使用的ANSI语法。
它通常被认为更具可读性,特别是当您连接许多表时。
当需要时,还可以轻松地用OUTER JOIN替换它。
WHERE语法更面向关系模型。
两个表连接的结果是应用筛选器的表的笛卡尔积,筛选器只选择连接列匹配的行。
使用WHERE语法更容易看到这一点。
至于你的例子,在MySQL中(通常在SQL中),这两个查询是同义词。
另外,请注意MySQL也有一个STRAIGHT_JOIN子句。
使用这个子句,可以控制JOIN顺序:在外部循环中扫描哪个表,在内部循环中扫描哪个表。
在MySQL中不能使用WHERE语法来控制这一点。