这两者之间有什么区别:
select t1.a1, t1.a2, t1.a3 from t1 cross join t2 where t1.a3 = t2.a1
并且:
select t1.a1, t1.a2, t1.a3 from t1,t2 where t1.a3=t2.a1;
我能够交替使用它们吗?
这两者之间有什么区别:
select t1.a1, t1.a2, t1.a3 from t1 cross join t2 where t1.a3 = t2.a1
并且:
select t1.a1, t1.a2, t1.a3 from t1,t2 where t1.a3=t2.a1;
我能够交替使用它们吗?
SQL有以下几种连接类型,全部来自于集合论:
内连接。From A inner join B
等同于A ∩ B,提供两个集合都共有的元素集合。
左连接。From A left outer join B
等同于(A − B) ∪ (A ∩ B)。每个A至少会出现一次;如果有多个匹配的B,则每个匹配的B都会重复一次。
右连接。From A right outer join B
等同于(A ∩ B) ∪ (B − A)。它与表交换位置的左连接完全相同。每个B至少会出现一次;如果有多个匹配的A,每个匹配的B都会重复一次。
全连接。From A full outer join B
等同于(A − B) ∪ (A ∩ B) ∪ (B − A)。每个A和每个B都至少会出现一次。如果一个A匹配多个B,则每个匹配的A都会重复一次;如果一个B匹配多个A,则每个匹配的B都会重复一次。
交叉连接。From A cross join B
产生A × B的笛卡尔积。每个A将为每个B重复一次。如果A有100行,B也有100行,则结果集将包含10,000行。
应该注意到,select
查询的理论执行包括按照以下顺序执行的步骤:
计算from
子句中源集合的完全笛卡尔积以启动候选结果集。
根据from
子句中的连接条件,缩小候选结果集。
根据where
子句中的条件,进一步缩小候选结果集。
根据group by
子句中的条件,将候选结果集分成组。
从候选结果集中删除除与group by
子句相关或与聚合函数评估相关的列之外的任何列。
为候选结果集中的每个组计算任何此类聚合函数的值。
将候选结果集中的每个组折叠成一个单行,其中包括分组列和计算出的每个聚合函数的值。现在,候选结果集每个组对应一行,除了group by
列或该组的聚合函数的计算值之外,所有列都被消除。
根据having
子句中的条件缩小候选结果集并生成最终结果集。
按照order by
子句中的条件对最终结果集进行排序并输出结果。
还有更多步骤与compute
和compute by
子句有关,但这已足以了解其工作原理。
还应注意的是,除了最简单的实现方式外,没有什么会真正按照这种方式评估select
语句,但产生的结果必须与完全执行上述步骤时产生的结果相同。
MySQL没有区分JOIN
和CROSS JOIN
。它们是相同的。
在你的两个示例中,这个子句
WHERE t1.a3 = t2.a1
SELECT t1.a1, t1.a2, t1.a3
FROM t1
JOIN t2 ON t1.a3 = t2.a1
没有区别,尽管可以对此微笑。首先进行交叉连接,然后使用where语句将其转换为内部连接(至少在第一个join中)。这种写法超过20年了,在复杂语句中容易出现错误。我建议使用新的花式写法,像这样:
select t1.a1, t1.a2, t1.a3
from t1
inner join t2 on t1.a3 = t2.a1
join
语法。其他方法是允许的,但它们不具备外连接的灵活性。 - Gordon Linoff