Sql 完全外部联接意外结果
我有两张桌子:Sql 完全外部联接意外结果,sql,outer-join,proc-sql,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
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
当我进行联合时,我得到了预期的结果:
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
然而,当使用完全外部联接时,我会丢失值,我不明白为什么。它应该产生和联合一样的结果,对吗?
据我所知,它应该生成两个表中的所有记录以及任何匹配的记录。显然情况并非如此
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
.
.
我错过了什么?
如果这有什么不同的话,我是在procsql中完成的
感谢您的帮助:)
运行此命令,看看您错过了什么:
select *
FROM A FULL OUTER JOIN B
ON A.ID = B.ID
;
运行此命令,看看您错过了什么:
select *
FROM A FULL OUTER JOIN B
ON A.ID = B.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;
如果满足以下条件,则这与联合
相同:
列在每个表中都是唯一的id
- 当
s匹配时,数据列具有相同的值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;
这篇评论太长了 为什么您会认为
完全外部联接
会产生与联合
相同的结果?那真的不是正确的想法。在您的情况下,您可以编写查询,通过执行以下操作使其接近真实:
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;
如果满足以下条件,则这与联合
相同:
列在每个表中都是唯一的id
- 当
s匹配时,数据列具有相同的值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;
将联合视为附加。从第一个表中收集所有记录,然后从第二个表中收集所有记录。两个表中的列都需要匹配位置和类型,但不需要匹配名称。最后删除所有选定列中数据完全重复的记录 Union All将不执行重复删除 这有助于从部分列表构建总列表。就像美国的城市可能是一张桌子,加拿大的城市可能是另一张桌子。名称可能不同(州与省、邮政编码与邮政编码),但根据在选择列表中的位置,可以在同一列中结束。(省将显示在州栏中…) 另一方面,连接被设计为垂直扩展数据,尽管正如Gordon指出的,您可以使用完整的外部连接来模拟联合。尽管它相当于UNIONALL,并且不会像union那样删除重复项,除非在外部包装查询中添加distinct 这将允许您添加相关但存储在不同表中的数据。例如,向客户添加订单信息,并可能向订单添加订单详细信息。当一个表中的记录在另一个表中有许多匹配项时,这将创建重复数据
这只是一个简短的概述,有大量关于联合和联接的文章和教程。将联合视为附加。从第一个表中收集所有记录,然后从第二个表中收集所有记录。两个表中的列都需要匹配位置和类型,但不需要匹配名称。最后删除所有选定列中数据完全重复的记录 Union All将不执行重复删除 这有助于从部分列表构建总列表。就像美国的城市可能是一张桌子,加拿大的城市可能是另一张桌子。名称可能不同(州与省、邮政编码与邮政编码),但根据在选择列表中的位置,可以在同一列中结束。(省将显示在州栏中…) 另一方面,连接被设计为垂直扩展数据,尽管正如Gordon指出的,您可以使用完整的外部连接来模拟联合。尽管它相当于UNIONALL,并且不会像union那样删除重复项,除非在外部包装查询中添加distinct 这将允许您添加相关但存储在不同表中的数据。例如,向客户添加订单信息,并可能向订单添加订单详细信息。当一个表中的记录在另一个表中有许多匹配项时,这将创建重复数据
这只是一个简短的概述,有大量关于联合和联接的文章和教程。TL;DR完全外部联接是左外部联接和右外部联接的并集,左外部联接和右外部联接是内部联接并集,由空值扩展的不匹配的左行和右行(分别)组成。所以外部连接相当于东西的并集,但是,与并集不同,东西不是它的参数,而是从它的参数派生出来的东西。如果参数具有相同的列,则不会添加任何空值,但我们仍然可以看到完整的外部联接是左外部联接和右外部联接的并集,左外部联接和右外部联接是内部联接,分别与不匹配的左行和右行并集;这三个国家都不是工会
使用关系术语,如果每个属性域中的值为NULL,则两个无NULL输入的自然完全外部联接将返回三个表的并集:输入的自然联接、由NULL扩展的左输入的不匹配行和由NULL扩展的右输入的不匹配行。所以(在这些假设下)并集可以被自然的完全外接所取代 在SQL中,由于重复的行、有序的列、空值被运算符视为特殊值、空值在确定连接与联合的子对象何时不同时的使用方式不同,以及FROM涉及非自然叉积这一事实,这种情况变得复杂。大多数数据库管理系统也不提供完整的或相应的 SQL完全外部联接返回一个包,其中包含输入的内部联接中的行以及unm