FULL OUTER JOIN意外结果

时间:2016-11-29 17:24:50

标签: sql outer-join proc-sql

我有这两个表:

TABLE A:
ID  COUNTRY  CAPITAL    CONTINENT
1   Slovakia Bratislava Europe
2   Senegal  Dakar      Africa
3   Brazil   Brasilia   South America
4   Wales    Cardiff    Europe
5   Egypt    Cairo      Africa

TABLE B:
ID  COUNTRY   CAPITAL      CONTINENT
5   Egypt     Cairo        Africa
6   Argentina Buenos Aires South America
7   Hungary   Budapest     Europe
2   Senegal   Dacar        Africa

当我做UNION时,我得到了预期的结果:

CREATE TABLE COMB_UNION AS 

    SELECT * FROM A
    UNION 
    SELECT * FROM B;

1   Slovakia    Bratislava  Europe
2   Senegal Dacar   Africa
2   Senegal Dakar   Africa
3   Brazil  Brasilia    South America
4   Wales   Cardiff Europe
5   Egypt   Cairo   Africa
6   Argentina   Buenos Aires    South America
7   Hungary Budapest    Europe

但是,在使用FULL OUTER JOIN时我会得到缺失的值,而我不明白为什么。它应该产生与UNION相同的结果,对吧? 据我了解,它应该产生来自两个表和任何匹配记录的所有记录。显然不是这样的

CREATE TABLE OUTER_JOIN AS 

        SELECT 
            A.ID, A.COUNTRY, A.CAPITAL, A.CONTINENT 
            FROM A FULL OUTER JOIN B 
            ON A.ID = B.ID;

1   Slovakia    Bratislava  Europe
2   Senegal Dakar   Africa
3   Brazil  Brasilia    South America
4   Wales   Cardiff Europe
5   Egypt   Cairo   Africa
.           
.       

我在这里缺少什么? 我在PROC SQL中这样做,如果这有任何区别。

任何帮助表示赞赏:)

4 个答案:

答案 0 :(得分:0)

select      coalesce(A.ID       ,B.ID)         as ID
           ,coalesce(A.COUNTRY  ,B.COUNTRY)    as COUNTRY
           ,coalesce(A.CAPITAL  ,B.CAPITAL)    as CAPITAL
           ,coalesce(A.CONTINENT,B.CONTINENT)  as CONTINENT

FROM        A FULL OUTER JOIN B 
            ON A.ID = B.ID
;

运行此功能,查看您错过的内容:

select      *

FROM        A FULL OUTER JOIN B 
            ON A.ID = B.ID
;

答案 1 :(得分:0)

评论太长了。

为什么您认为full outer join会产生与union相同的结果?那真是不正确的思考。在您的情况下,可以编写查询,以便通过执行以下操作接近真实:

CREATE TABLE OUTER_JOIN AS 
    SELECT COALESCE(A.ID, B.ID) as ID,
           COALESCE(A.COUNTRY, B.COUNTRY) as COUNTRY,
           COALESCE(A.CAPITAL, B.CAPITAL) as CAPITAL,
           COALESCE(A.CONTINENT, B.CONTINENT) as CONTINENT
     FROM A FULL OUTER JOIN
          B 
          ON A.ID = B.ID;

如果满足以下条件,则与UNION相同:

  • id列在每个表格中都是唯一的。
  • id匹配时,数据列具有相同的值。

您的数据不是这样。如果匹配所有列,则可以得到相同的结果:

CREATE TABLE OUTER_JOIN AS 
    SELECT COALESCE(A.ID, B.ID) as ID,
           COALESCE(A.COUNTRY, B.COUNTRY) as COUNTRY,
           COALESCE(A.CAPITAL, B.CAPITAL) as CAPITAL,
           COALESCE(A.CONTINENT, B.CONTINENT) as CONTINENT
     FROM A FULL OUTER JOIN
          B 
          ON A.ID = B.ID AND A.COUNTRY = B.COUNTRY AND
             A.CAPITAL = B.CAPITAL AND A.CONTINENT = B.CONTINENT;

答案 2 :(得分:0)

将联盟视为追加。从第一个表中收集所有记录,然后从第二个表中收集所有记录。两个表中的列需要匹配位置和类型,但不能匹配名称。最后删除所有选定列中包含完全重复数据的记录。

Union All不会执行重复删除。

这些适用于从部分列表构建总列表。像美国的城市可能只有一张桌子,加拿大的城市也可能在另一张桌子上。名称可能不同(州与省,邮政编码与邮政编码),但基于选择列表中的位置可能会在同一列中结束。 (省将出现在州列......)

另一方面,连接旨在垂直扩展数据,尽管Gordon指出你可以使用完整的外连接来模仿联合。虽然它将等同于union all而不是像union一样删除重复项,除非你在外部的包装器查询中添加distinct。

这将允许您添加相关但存储在不同表中的数据。例如,向客户添加订单信息,并可能向订单添加订单详细信息。当一个表中的记录在另一个表中有许多匹配时,这将创建重复数据。

这只是一个快速的概述,关于联合和联接的文章和教程很多。​​

答案 3 :(得分:0)

TL; DR 全外连接是左外连接和&的联合。右外连接,左和外连接右外连接是内连接与无与伦比的左连接和...右(分别)行由空值扩展。所以外部联接等同于联合的东西,但是,与联盟不同,这些东西不是它的论点,它是从它的论证中衍生出来的东西。如果参数具有相同的列,则不会添加任何空值,但我们仍然认为完全外部连接是左外连接和&的并集。右外连接,左和外连接右外连接是内连接与无与伦比的左连接和...右(分别)行;这三者都不是联盟。

使用关系术语,如果我们在每个属性域中都有NULL,则两个无NULL输入的NATURAL FULL OUTER JOIN返回三个表的UNION:输入的NATURAL JOIN,左输入的不匹配行扩展通过NULL和由NULL扩展的右输入的不匹配行。所以(在这些假设下)UNION可以用NATURAL FULL OUTER JOIN代替。

在SQL中,情况因复制行,有序列,操作符将NULL视为特殊值,在确定JOIN与UNION的子行何时不同时使用NULL以及FROM涉及非事实这一事实而变得复杂天然的十字产品。大多数DBMS也不提供完全或相应的。

SQL FULL OUTER JOIN返回一个包,其中包含输入的INNER JOIN中的行以及由NULL扩展的每个输入的不匹配行。

假设输入都没有重复行或NULL,则SQL UNION CORRESPONDING由NATURAL FULL OUTER JOIN给出。

给出了UNION
SELECT COALESCE(left.L1, right.R1) AS L1, ...
FROM left FULL OUTER JOIN right
ON left.L1 = right.R1 AND ...
所有列的

,由UNION配对。

一旦允许带有重复项和/或NULL的输入,就OUTER JOIN和其他运算符表示UNION变得复杂。例如:假设我们在两个输入中都有相同的NULL行。 UNION会将这些视为不同,因此输出中有一行;但是FULL OUTER JOIN将输出两行。

SQLFiddle

当您希望行满足一个输入或其他输入的成员资格标准(谓词)时,请使用UNION。如果希望行满足一个AND的成员条件,并且只需要一个其他列的OR,则使用OUTER JOIN。根据OUTER JOIN的复杂语义/行为,没有理由模拟UNION的简单语义/行为。