CROSS JOIN 是没有 ON 子句的 INNER JOIN 的同义词吗?

Posted

技术标签:

【中文标题】CROSS JOIN 是没有 ON 子句的 INNER JOIN 的同义词吗?【英文标题】:Is CROSS JOIN a synonym for INNER JOIN without ON clause? 【发布时间】:2011-08-10 04:13:27 【问题描述】:

我想知道CROSS JOIN 是否可以在任何查询中安全地替换为INNER JOIN

没有ONUSINGINNER JOIN 是否与CROSS JOIN 完全相同?如果是,是否发明了 CROSS JOIN 类型只是为了在查询中更好地表达意图?

这个问题的附录是:

在使用CROSS JOIN ... WHERE xINNER JOIN ... ON ( x )INNER JOIN ... WHERE ( x ) 时,使用现代和广泛使用的 DBMS 会有什么不同吗?

谢谢。

【问题讨论】:

【参考方案1】:

在所有现代数据库中,所有这些结构都针对相同的计划进行了优化。

某些数据库(如SQL Server)需要ON 条件在INNER JOIN 之后,因此您的第三个查询不会在那里解析。

表的可见范围是JOIN 顺序,所以这个查询:

SELECT  *
FROM    s1
JOIN    s2
ON      s1.id IN (s2.id, s3.id)
CROSS JOIN
        s3

不会解析,而这个:

SELECT  *
FROM    s2
CROSS JOIN
        s3
JOIN    s1
ON      s1.id IN (s2.id, s3.id)

会的。

【讨论】:

感谢您的回答。根据INNER JOINs 的标准,ON 条件是强制性的吗? @Benoit:根据SQL-92,它不是。不过,我手边没有20032008 的副本。除了mysql 之外的所有数据库都需要它。 @Benoit:我的意思是“四大的所有数据库”,抱歉 :) @Quassnoi:这是指 Oracle、MySQL、PostgreSQL 和 SQL Server 吗? 在第二个版本的查询中,我认为您的意思是“FROM s2”。它不会按原样解析。可以说值得一票(这不是我的),但它很容易解决。【参考方案2】:

原始交叉联接是一种没有 where 子句的交叉联接,这意味着为要联接的左右表的每个组合生成一条记录,并在没有左侧或右侧数据的地方插入空值。

如果您将 where 子句添加到交叉连接,这将使其等同于内部连接,因为 where 子句与内部连接中的 ON 执行相同的操作。

但是,内连接通常更适合使用,因为它可以将 ON 条件与其余的 where 子句分开,从而更容易理解。

【讨论】:

在您的第一段中,您混淆了 CROSS 和 OUTER 连接。与空表交叉连接会产生空结果。

以上是关于CROSS JOIN 是没有 ON 子句的 INNER JOIN 的同义词吗?的主要内容,如果未能解决你的问题,请参考以下文章

Redshift Cross join忽略where子句

SQL中inner join,outer join和cross join的区别

带有 ON 子句或替代方法的休眠 LEFT JOIN FETCH

(', CROSS, FULL, INNER, JOIN, LEFT, NATURAL, ON, RIGHT 或 USING 预期,得到'WITH'

JOIN 的 ON 子句中引用的表的顺序是不是重要?

常量值如何影响 Join 的 ON 子句?