大多数SQL方言同时接受以下两种查询:
SELECT a.foo, b.foo
FROM a, b
WHERE a.x = b.x
SELECT a.foo, b.foo
FROM a
LEFT JOIN b ON a.x = b.x
显然,当您需要外部连接时,需要使用第二种语法。但是,在进行内部连接时,为什么我应该更喜欢第二种语法而不是第一种语法(反之亦然)?
大多数SQL方言同时接受以下两种查询:
SELECT a.foo, b.foo
FROM a, b
WHERE a.x = b.x
SELECT a.foo, b.foo
FROM a
LEFT JOIN b ON a.x = b.x
显然,当您需要外部连接时,需要使用第二种语法。但是,在进行内部连接时,为什么我应该更喜欢第二种语法而不是第一种语法(反之亦然)?
当前回答
我听到很多人抱怨第一个太难理解了,它是不清楚的。我不认为它有问题,但在讨论之后,为了清晰起见,我甚至在INNER JOINS上使用了第二个。
其他回答
我认为在本文中有一些很好的理由采用第二种方法——使用显式join。关键在于,当JOIN条件从WHERE子句中删除后,在WHERE子句中查看其余的选择条件就容易得多了。
在非常复杂的SELECT语句中,读者更容易理解正在发生的事情。
第一种方法是较老的标准。第二种方法是在SQL-92中引入的http://en.wikipedia.org/wiki/SQL。完整的标准可以在http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt上查看。
数据库公司花了很多年才采用SQL-92标准。
所以第二种方法是首选的原因,它是根据ANSI和ISO标准委员会的SQL标准。
第二种是首选的,因为它不太可能因为忘记放置where子句而导致意外交叉连接。没有on子句的连接将无法进行语法检查,没有where子句的旧式连接不会失败,它将进行交叉连接。
此外,当您以后必须使用左连接时,将它们都置于相同的结构中对维护是有帮助的。旧的语法自1992年以来就已经过时了,现在早就该停止使用它了。
另外,我发现许多只使用第一种语法的人并不真正理解连接,而理解连接对于在查询时获得正确的结果至关重要。
当你需要一个外部连接时,第二个语法并不总是必需的:
Oracle:
SELECT a.foo, b.foo
FROM a, b
WHERE a.x = b.x(+)
MSSQLServer(尽管在2000版本中已弃用)/Sybase:
SELECT a.foo, b.foo
FROM a, b
WHERE a.x *= b.x
回到你的问题。我不知道答案,但它可能与这样一个事实有关:当您正在做连接时,连接比在where子句中添加表达式更自然(至少在语法上)。
JOIN语法将条件保存在它们应用的表附近。这在连接大量表时尤其有用。
顺便说一下,你也可以用第一个语法做一个外部连接:
WHERE a.x = b.x(+)
Or
WHERE a.x *= b.x
Or
WHERE a.x = b.x or a.x not in (select x from b)