SQL Server 中的 CROSS JOIN 和 FULL OUTER JOIN 有什么区别?
它们是否相同?请解释。什么时候会使用其中任何一种?
交叉连接在两个表之间产生一个笛卡尔积,返回所有行的所有可能组合。它没有 on
子句,因为您只是将所有内容加入到所有内容中。
full outer join
是 left outer
和 right outer
联接的组合。它返回两个表中与查询的 where
子句匹配的所有行,如果这些行不能满足 on
条件,它会将 null
值放入未填充的字段中。
这篇 wikipedia 文章通过给出一组示例表的输出示例解释了各种类型的连接。
对某些人来说可能并不总是显而易见的一件事是,与空表(或结果集)的交叉连接会导致空表(M x N;因此 M x 0 = 0)
除非 M 和 N 都为 0,否则完全外连接将始终包含行。
我想在其他答案中添加一个重要方面,它实际上以最好的方式向我解释了这个主题:
如果 2 个连接表包含 M 和 N 行,则交叉连接将始终产生 (M x N) 行,但完全外连接将产生从 MAX(M,N) 到 (M + N) 行(取决于实际行数匹配“on”谓词)。
编辑:
从逻辑查询处理的角度来看,CROSS JOIN 确实总是产生 M x N 行。 FULL OUTER JOIN 发生的情况是左右表都被“保留”,就好像 LEFT 和 RIGHT 连接都发生了一样。因此,来自左表和右表的不满足 ON 谓词的行被添加到结果集中。
cross join
是表格的倍数; full outer join
在最坏的情况下添加它们,具体取决于匹配的行数。
对于 SQL Server,CROSS JOIN and FULL OUTER JOIN
不同。 CROSS JOIN
只是两个表的笛卡尔积,与任何过滤条件或任何条件无关。
FULL OUTER JOIN
给出两个表的 LEFT OUTER JOIN and RIGHT OUTER JOIN
的唯一结果集。它还需要 ON 子句来映射两列表。
表 1 包含 10 行,表 2 包含 20 行,其中 5 行在特定列上匹配。然后 CROSS JOIN 将在结果集中返回 10*20=200 行。 FULL OUTER JOIN 将在结果集中返回 25 行。 INNER JOIN 将返回匹配的行,因此结果集中有 5 行。 FULL OUTER JOIN(或任何其他 JOIN)始终返回小于或等于笛卡尔积编号的结果集。 FULL OUTER JOIN 返回的行数等于(LEFT OUTER JOIN 的行数)+(RIGHT OUTER JOIN 的行数)-(INNER JOIN 的行数)。
除了返回的 NULL 值之外,它们是相同的概念。
见下文:
declare @table1 table( col1 int, col2 int );
insert into @table1 select 1, 11 union all select 2, 22;
declare @table2 table ( col1 int, col2 int );
insert into @table2 select 10, 101 union all select 2, 202;
select
t1.*,
t2.*
from @table1 t1
full outer join @table2 t2 on t1.col1 = t2.col1
order by t1.col1, t2.col1;
/* full outer join
col1 col2 col1 col2
----------- ----------- ----------- -----------
NULL NULL 10 101
1 11 NULL NULL
2 22 2 202
*/
select
t1.*,
t2.*
from @table1 t1
cross join @table2 t2
order by t1.col1, t2.col1;
/* cross join
col1 col2 col1 col2
----------- ----------- ----------- -----------
1 11 2 202
1 11 10 101
2 22 2 202
2 22 10 101
*/
交叉连接:交叉连接产生的结果由来自两个或多个表的行的每个组合组成。这意味着如果表 A 有 3 行,表 B 有 2 行,则 CROSS JOIN 将产生 6 行。这两个表之间没有建立关系——你实际上只是产生了所有可能的组合。
全外连接:全外连接既不是“左”也不是“右”——两者都是!它包括参与 JOIN 的两个表或结果集中的所有行。当 JOIN 左侧的行不存在匹配行时,您会在“右侧”的结果集中看到 Null 值。相反,当 JOIN 的“右侧”侧的行不存在匹配的行时,您会在“左侧”的结果集中看到 Null 值。
SQL 完全外连接
FULL OUTER JOIN 返回左表 (table1) 和右表 (table2) 中的所有行,与匹配无关。
FULL OUTER JOIN 关键字结合了 LEFT OUTER JOIN 和 RIGHT OUTER JOIN 的结果
SQL 全外连接也称为 FULL JOIN
参考:http://datasciencemadesimple.com/sql-full-outer-join/
SQL 交叉连接
在 SQL CROSS JOIN 中,第一个表的每一行都映射到第二个表的每一行。
CROSS JOIN 操作的结果集产生的行数等于第一个表中的行数乘以第二个表中的行数。
CROSS JOIN 也称为笛卡尔积/笛卡尔连接
表 A 中的行数为 m,表 B 中的行数为 n,结果表将有 m*n 行
参考:http://datasciencemadesimple.com/sql-cross-join/
交叉加入:http://www.dba-oracle.com/t_garmany_9_sql_cross_join.htm
TLDR;在 2 个表之间生成所有可能的组合(Carthesian 积)
(完全)外部连接:http://www.w3schools.com/Sql/sql_join_full.asp
TLDR;返回两个表中的每一行以及具有相同值的结果(匹配条件)
完全外连接结合了左外连接和右外连接。结果集从两个表中返回满足条件的行,但返回不匹配的空列。
交叉连接是一种不需要任何条件来连接表的 Cartesian product。结果集包含的行和列是两个表的乘积。
想对常见的连接类型增加直觉。想想参数化的连接伪运算符:
function generalJoin(
forceIncludeLeft: boolean, forceIncludeRight: boolean, condition: Expression,
tableA: Table, tableB: Table
) {
for (leftRow in tableA) {
for (rightRow in tableB) {
// Output combined row if condition is true
if (condition(leftRow, rightRow)) {
markRowHasMatch(leftRow);
markRowHasMatch(rightRow);
output(leftRow.append(rightRow));
}
}
}
if (forceIncludeLeft) {
for (leftRow in tableA) {
if (!rowHasMatch(leftRow)) {
output(leftRow.append(createArrayOfNulls(tableB.columnsCount)));
}
}
}
if (forceIncludeRight) {
for (rightRow in tableB) {
if (!rowHasMatch(rightRow)) {
output(createArrayOfNulls(tableA.columnsCount).append(rightRow));
}
}
}
}
// We may think of Expression as function taking rowA and rowB and
// returning boolean true or false
function alwaysTrue(rowA, rowB) {
return true;
}
这相当于
[SELECT ...] from tableA SOMEJOIN tableB ON condition
那么这是等价表:
a [INNER] JOIN b ON condition <=> generalJoin(false, false, condition, a, b)
a LEFT [OUTER] JOIN b ON condition <=> generalJoin(true, false, condition, a, b)
a RIGHT [OUTER] JOIN b ON condition <=> generalJoin(false, true, condition, a, b)
a FULL [OUTER] JOIN b ON condition <=> generalJoin(true, true, condition, a, b)
a CROSS JOIN b <=> generalJoin(false, false, alwaysTrue, a, b)
实际上,CROSS JOIN 等效于无条件的 INNER JOIN,即每个左行都匹配每个右行。
不定期副业成功案例分享
FROM t1 FULL OUTER JOIN t2 ON t1.id=t2.id
总是比FROM t1,t2 WHERE t1.id=t2.id
快?outer join
更快还是cross join
?