大多数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
显然,当您需要外部连接时,需要使用第二种语法。但是,在进行内部连接时,为什么我应该更喜欢第二种语法而不是第一种语法(反之亦然)?
当前回答
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)
其他回答
如果两者都是内部连接,则在SQL的语义或执行或性能上没有区别。这纯粹是一个偏好的问题,编码标准在你的工作小组。
在过去的25年里,我养成了一个习惯,如果我有一个相当复杂的SQL,我将使用INNER JOIN语法,因为它更容易让读者一眼看出查询的结构。它还通过从剩余条件中分离出连接条件来提供更多的清晰度,这可以节省时间(和错误),如果您在几个月后返回查询的话。
但是对于外部连接,为了清晰起见,我在任何情况下都不会使用非ansi扩展。
我听到很多人抱怨第一个太难理解了,它是不清楚的。我不认为它有问题,但在讨论之后,为了清晰起见,我甚至在INNER JOINS上使用了第二个。
对于数据库来说,它们最终是相同的。但是,对于您来说,在某些情况下必须使用第二种语法。为了编辑最终不得不使用它的查询(发现您需要一个左连接,而您有一个直连接),为了一致性,我只在第二个方法上设置模式。这将使阅读查询更容易。
我认为在本文中有一些很好的理由采用第二种方法——使用显式join。关键在于,当JOIN条件从WHERE子句中删除后,在WHERE子句中查看其余的选择条件就容易得多了。
在非常复杂的SELECT语句中,读者更容易理解正在发生的事情。
基本上,当你的FROM子句像这样列出表时:
SELECT * FROM
tableA, tableB, tableC
结果是表a, B, c中的所有行的叉乘。然后你应用限制WHERE表a。id = tableB。A_id将丢弃大量的行,然后进一步…和表b。id = tableC。B_id,然后你应该只得到那些你真正感兴趣的行。
dbms知道如何优化此SQL,以便使用join编写此SQL的性能差异可以忽略不计(如果有的话)。使用JOIN表示法使SQL语句更具可读性(恕我直言,不使用JOIN会使语句变得一团糟)。使用叉乘,您需要在WHERE子句中提供连接标准,这就是符号的问题所在。你在WHERE从句里塞满了
tableA.id = tableB.a_id
AND tableB.id = tableC.b_id
它只用于限制叉乘。WHERE子句应该只包含结果集的RESTRICTIONS。如果将表连接条件与结果集限制混合使用,您(和其他人)将发现查询更难阅读。您一定要使用join,并保留FROM子句和WHERE子句。