【问题标题】:SQL Server: What is the difference between CROSS JOIN and FULL OUTER JOIN?SQL Server:CROSS JOIN 和 FULL OUTER JOIN 有什么区别?
【发布时间】:2011-03-14 19:40:50
【问题描述】:

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

它们是否相同?请解释。什么时候可以使用其中任何一种?

【问题讨论】:

    标签: sql-server cross-join full-outer-join


    【解决方案1】:

    对于 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)总是返回小于或等于 Cartesian Product number 的结果集。

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

    【讨论】:

      【解决方案2】:

      它们是相同的概念,除了返回的 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
      */
      

      【讨论】:

      • 很好的例子!
      • 感谢真实数据示例。这样就更清楚了。
      【解决方案3】:

      完全外连接结合了左外连接和右外连接。结果集从两个表中返回满足条件的行,但返回不匹配的空列。

      交叉连接是一个Cartesian product,它不需要任何条件来连接表。结果集包含的行和列是两个表的乘积。

      【讨论】:

        【解决方案4】:

        交叉加入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;返回两个表中的每一行以及具有相同值的结果(匹配条件)

        【讨论】:

          【解决方案5】:

          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/

          【讨论】:

            【解决方案6】:

            这是一个示例,其中 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 行受影响)

            【讨论】:

            • 这个例子似乎是试图复制上面给出的例子(40 个月前提供),正如前面的例子所示,你不需要“on 1 = 1”位。
            【解决方案7】:

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

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

            编辑:

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

            【讨论】:

            • 这些边界是否排除了可能的 1-many 匹配?完全外连接仍然能够产生 (M x N) 行。
            • select COUNT_BIG(*) FROM Traffic t CROSS JOIN Recipient r 和 SELECT COUNT_BIG(*) FROM Traffic t FULL JOIN Recipient r ON (1=1) 他们是一样的。
            • 你的答案是最好的真实答案。基本上:cross join 是表格的倍数; full outer join 在最坏的情况下添加它们,具体取决于匹配的行数..
            • 这是错误的。 FULL JOIN ON rows 是 INNER JOIN ON rows UNION ALL 不匹配的左表行空扩展 UNION ALL 不匹配的右表行空扩展。所以 FULL JOIN 可以返回 M*N 行——可能大于 MAX(M,N) 和 M+N。但无论如何,作为 M 和 N 函数返回的最小和最大行数 只是没有用。有用的是FULL JOIN ON 的明确定义——就 INNER JOIN ON 和不匹配的行而言。
            • 你能回复@philipxy 的评论吗?在我看来,philipxy 是正确的,而您的答案是不正确的。似乎外部联接(甚至内部联接)可能具有多于 M+N 行(例如,True 上的联接将等效于交叉联接并产生 M*N 行)。也许您的计算假设对具有唯一值的列进行外部连接(例如,在主键上)?还是我错过了什么?
            【解决方案8】:

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

            除非 M 和 N 都为 0,否则完全外连接将始终包含行。

            【讨论】:

              【解决方案9】:

              交叉连接:交叉连接产生的结果由来自两个或多个表的行的每个组合组成。这意味着如果表 A 有 3 行,表 B 有 2 行,则 CROSS JOIN 将产生 6 行。这两个表之间没有建立关系——实际上你只是产生了所有可能的组合。

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

              【讨论】:

                【解决方案10】:

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

                full outer joinleft outerright outer 连接的组合。它返回两个表中与查询的where 子句匹配的所有行,如果这些行不能满足on 条件,它会将null 值放入未填充的字段中。

                这篇wikipedia 文章解释了各种类型的连接,并给出了一组示例表的输出示例。

                【讨论】:

                • 那么在大表的情况下FROM t1 FULL OUTER JOIN t2 ON t1.id=t2.id 总是比FROM t1,t2 WHERE t1.id=t2.id 快?
                • @alexkovelsky 内连接通常在两个表之间几乎没有匹配项时更快,因为使用索引意味着它不会费心读取其中一个表上的所有行。完全外连接必须始终读取两个表(或相关索引)中的所有行。在索引不够的情况下,或者必须读取底层堆以输出所需的列,则完全外连接几乎总是比内连接慢。
                • outer join 更快还是cross join
                • @Shafizadeh - 他们做不同的事情。
                • 如果我在 True 上使用 FULL OUTER JOIN 会怎样?结果/性能是否类似于 CROSS JOIN?
                猜你喜欢
                • 2010-09-07
                • 2016-08-28
                • 2013-10-16
                • 2020-03-07
                相关资源
                最近更新 更多