SQL内部联接实现为隐式联接

SQL内部联接实现为隐式联接,sql,inner-join,hsqldb,cross-join,Sql,Inner Join,Hsqldb,Cross Join,最近,我遇到一个SQL查询,如下所示: SELECT * FROM A, B WHERE A.NUM = B.NUM 在我看来,这似乎将返回与内部联接完全相同的结果: 有没有合理的理由让人们在这里使用交叉连接?编辑:似乎大多数SQL应用程序都会在这里自动使用内部联接 数据库为HSQLDB是,两条语句将返回相同的结果。用哪一种是口味的问题。每一个sane数据库系统都将使用连接(如果可能的话),没有一个sane优化器会在第一种情况下真正使用交叉乘积 但是请注意,您的第一个语法不是交叉连接。它只是连

最近,我遇到一个SQL查询,如下所示:

SELECT * FROM A, B WHERE A.NUM = B.NUM
在我看来,这似乎将返回与内部联接完全相同的结果:

有没有合理的理由让人们在这里使用交叉连接?编辑:似乎大多数SQL应用程序都会在这里自动使用内部联接


数据库为HSQLDB

是,两条语句将返回相同的结果。用哪一种是口味的问题。每一个sane数据库系统都将使用连接(如果可能的话),没有一个sane优化器会在第一种情况下真正使用交叉乘积


但是请注意,您的第一个语法不是交叉连接。它只是连接的隐式表示法,没有指定要使用哪种连接。相反,优化器必须检查WHERE子句以确定是使用内部联接还是交叉联接:如果在WHERE子句中找到了适用的联接条件,这将导致内部联接。如果没有找到这样的子句,将导致交叉联接。由于第一个示例指定了一个适用的连接条件,其中A.NUM=B.NUM这将导致内部连接,因此与第二个示例完全相同。

较旧的语法是SQL反模式。只要您看到它,就应该将其替换为内部联接。它是反模式的部分原因是,无法判断是否打算使用交叉连接,也无法判断是否允许使用where类。这会导致许多意外的交叉连接,特别是在复杂查询中。此外,在某些数据库中,特别是在Sql server中,隐式外部联接不能正常工作,因此人们试图将显式联接和隐式联接结合起来,结果很糟糕,甚至没有意识到这一点。总之,即使考虑使用隐含连接也是一个很差的实践。 第一个连接不是交叉连接,它是内部连接的旧形式,连接条件位于WHERE中。查询是一样的。请您指定您正在使用的RDBMS,这样我们就不必猜测了。不,没有理由任何理智的人会在这里使用交叉连接。交叉连接意味着您需要一个笛卡尔积——虽然可以通过附加过滤器强制它像内部连接一样工作,但我看不出这有什么意义。如果需要内部联接,请使用内部联接;如果需要交叉连接,请使用交叉连接。不管开源文档怎么说,不管MySQL多么希望偏离SQL标准。我可以在很多没有明确禁止非机动车辆的高速公路上骑三轮车,但这并不意味着这样做是明智的或合乎逻辑的。在OP示例中,有人将关键字INNER替换为CROSS的唯一合理原因是他们使用的是MySQL,并且他们知道在MySQL JOIN中,INNER JOIN和CROSS JOIN是同义词。@spencer7593我不明白为什么一个理智的人会将INNER替换为CROSS,即使在极少数情况下它们是相同的。它们可以用于不同的目的,所以为什么不将它们分开,而不是提倡交换它们呢?Yosemite Sam可能是MySQL中允许内部连接而不使用ON子句的故障的原因,这一事实不是借口。尽管如此,我们仍然不知道OP是否在使用MySQL。我必须承认,交叉连接的MySQL语义非常奇怪。即使这在MySQL中是可能的,我也不会为一个并不意味着是真正的交叉产品的连接编写交叉连接。这将混淆查询的含义,并使不熟悉MySQL的读者发疯。不,这不是品味的问题。隐式连接是已知的SQL反模式。它们通常会导致显式连接无法解决的问题,例如意外交叉连接。隐式连接在20多年前就被取代了,现在是完全停止使用它们的时候了。有充分的理由表明,对于连接操作,JOIN关键字比老式的逗号语法更受欢迎。最大的原因之一是,如果使用逗号语法编写了错误的SQL,则很难找出错误所在。在ON子句中适当地使用JOIN关键字和JOIN谓词,可以更容易地发现SQL语句的错误。Joel在他十年前的博文中没有特别提到SQL,但我认为同样的原则也适用。
SELECT * FROM A INNER JOIN B ON A.NUM = B.NUM