SQL Server:CROSS JOIN和FULL OUTER JOIN有什么区别?


Answers:


243

交叉联接在两个表之间产生笛卡尔乘积,返回所有行的所有可能组合。它没有on子句,因为您只是将所有内容连接在一起。

A full outer join是a left outerright outerjoin 的组合。它返回两个表中与查询where子句匹配的所有行,并且在on无法满足这些行的条件的情况下,它将null为未填充的字段放入值。

这篇Wikipedia文章解释了各种类型的联接,并给出了示例表集的输出示例。


那么在大桌子的情况下 FROM t1 FULL OUTER JOIN t2 ON t1.id=t2.id 总是会比 FROM t1,t2 WHERE t1.id=t2.id
alexkovelsky

当两个表之间的匹配很少时,@ alexkovelsky内部联接通常会更快,因为使用索引意味着它不会打扰读取其中一个表上的所有行。完全外部联接必须始终读取两个表(或相关索引)中的所有行。如果索引不够,或者必须读取基础堆来输出所需的列,那么完整的外部联接几乎总是比内部联接慢。
Andrew Hill

1
outer join更快还是cross join
沙菲扎迪

2
@Shafizadeh-他们做不同的事情。
唐尼

9
如果我在True上进行完全外部加入怎么办?结果/性能是否与CROSS JOIN相似?
architectonic

65

对于某些人来说可能并不总是显而易见的一件事是,使用空表(或结果集)的交叉联接会导致空表(M x N;因此M x 0 = 0)

完全外部联接将始终具有行,除非M和N均为0。


32

我想在其他答案中添加一个重要方面,实际上以最佳方式向我解释了此主题:

如果2个联接表包含M和N行,则交叉联接将始终产生(M x N)行,但是完全外部联接将从MAX(M,N)到(M + N)行产生(取决于实际有多少行)匹配“在”谓词上)。

编辑:

从逻辑查询处理的角度来看,CROSS JOIN确实总是产生M x N行。FULL OUTER JOIN发生的情况是左表和右表都被“保留”,就好像左右连接都发生了一样。因此,来自左表和右表的行(不满足ON谓词)将添加到结果集中。


2
这些界限是否排除了可能的一对多比赛?完全外部联接仍然能够产生(M x N)行。
maxwellb 2012年

1
从流量t CROSS JOIN收件人r中选择COUNT_BIG(*)和从流量t FULL JOIN收件人r ON(1 = 1)中选择COUNT_BIG(*)。
urlreader

2
您的最佳答案。基本上是:cross join表的倍数;一个full outer join增加他们在最坏的情况下,这取决于有多少行匹配..
布赖恩·彼得森

是的。我一直在寻找这种数学- 从MAX(M,N)到(M + N)行产生 ..谢谢投票。
奥雅纳·拉希特

1
错了 FULL JOIN ON行是INNER JOIN ON行UNION ALL不匹配的左表行进行空扩展UNION ALL不匹配的右表行进行空扩展。因此FULL JOIN可以返回M * N行-可能大于MAX(M,N)和M + N。但是无论如何,作为M&N函数返回的最小和最大行数只是没有用。用INNER JOIN ON和不匹配的行来明确定义FULL JOIN ON是有用的。
philipxy

15

交叉联接:交叉联接产生的结果由两个或多个表的行的每种组合组成。这意味着如果表A有3行,表B有2行,则CROSS JOIN将导致6行。这两个表之间没有建立关系-实际上,您只是产生每种可能的组合。

完全外部联接:完全外部联接既不是“左”也不是“右”,两者都是!它包括参与JOIN的两个表或结果集中的所有行。当JOIN左侧的行不存在匹配行时,您将在右侧的结果集中看到Null值。相反,当JOIN右侧的行不存在匹配的行时,您会在左侧的结果集中看到Null值。


15

对于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行。

FULL OUTER JOIN(或任何其他JOIN)总是返回小于或等于的结果集Cartesian Product number

返回的行数FULL OUTER JOIN等于(的行数LEFT OUTER JOIN)+(的行数RIGHT OUTER JOIN)-(的行数INNER JOIN)。


8

除了返回的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
*/

1
很好的例子!
Lucas925

1
感谢您提供的真实数据示例。这使它更清晰。
dtc


2

完全外部联接将左外部联接和右外部联接组合在一起。结果集返回两个表中满足条件的行,但返回不匹配的空列。

交叉联接是笛卡尔积,不需要任何条件即可联接表。结果集包含行和列,它们是两个表的乘积。


1

这是一个示例,其中FULL OUTER JOIN和CROSS JOIN返回相同的结果集,而没有返回NULL。请注意,FULL OUTER JOIN的ON子句中的1 = 1:

declare @table1 table (     col1    int,    col2    int ) 
declare @table2 table (     col1    int,    col2    int )

insert into @table1 select  1, 11   union all select    2, 22   

insert into @table2 select  10, 101 union all select     2, 202

select  *
from    @table1 t1 full outer join @table2 t2
    on  1 = 1
(受影响的2行)

(受影响的2行)
col1 col2 col1 col2
----------- ----------- ----------- -----------
1 11 10 101
2 22 10 101
1 11 2 202
2 22 2 202
select  *
from    @table1 t1 cross join @table2 t2
col1 col2 col1 col2
----------- ----------- ----------- -----------
1 11 10 101
2 22 10 101
1 11 2 202
2 22 2 202

(受影响的4行)

1

SQL FULL OUTER JOIN

  • 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/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.