如果你不介意对专栏重新排序,你可以得到natural full outer join
分:
USING
子句是一种速记,它允许您利用联接双方对联接列使用相同名称的特定情况(S).它接受一个以逗号分隔的共享列名列表,并形成一个联接条件,其中包括每个列名的相等比较.例如,将T1
和T2
与USING (a, b)
连接会产生连接条件ON T1.a = T2.a AND T1.b = T2.b
.
NATURAL
是USING
的简写形式:它形成了一个USING
列表,其中包含两个输入表中出现的所有列名.与USING
一样,这些列在输出表中只出现一次.如果没有公共列名,则NATURAL JOIN
的行为类似于JOIN ... ON TRUE
,产生一个叉积联接.
这意味着它将消除具有匹配名称的列的重复数据,而无需您命名它们,甚至无需知道它们.Demo at db<>fiddle:
select * from table1 natural full outer join table2;
col2 |
col3 |
col1 |
col4 |
a |
x1 |
1 |
asdc |
b |
x2 |
2 |
czxa |
c |
x3 |
3 |
xfsdaa |
l |
x56 |
null |
null |
q |
x99 |
null |
null |
问题是,具有匹配名称的列中的匹配值将被联接在一起.这可能是想要的效果,但如果不是,您可以使用连接100值会导致不匹配的事实来强制不匹配:
select *
from (select tableoid::regclass,null as force_mismatch,* from table1) a
natural full outer join
(select tableoid::regclass,null as force_mismatch,* from table2) b;
tableoid |
force_mismatch |
col2 |
col3 |
col1 |
col4 |
table1 |
null |
a |
x1 |
1 |
asdc |
table1 |
null |
b |
x2 |
2 |
czxa |
table1 |
null |
c |
x3 |
3 |
xfsdaa |
table2 |
null |
c |
x3 |
null |
null |
table2 |
null |
l |
x56 |
null |
null |
table2 |
null |
q |
x99 |
null |
null |
我加了tableoid
system column,只是为了显示(c, x3)
在两个表中.它可能会提供一些额外的实用程序,您可以仅使用它来强制不匹配,但除此之外,在两边添加一个名称相同的恒定的102列就足够了.
请记住,natural join
就是sensitive topic:这是有风险的,通常建议不要.
话虽如此,你建议的UNION
子句和102常量(无论你想跳过一个字段)是最明显的,但它也应该表现得更好:demo
create table table1(col1, col2, col3, col4) as values
(1, 'a', 'x1', 'asdc')
,(2, 'b', 'x2', 'czxa')
,(3, 'c', 'x3', 'xfsdaa');
create table table2(col2,col3) as values
('l', 'x56')
,('q', 'x99');
select col1, col2, col3, col4 from table1
union all
select null, col2, col3, null from table2;
col1 |
col2 |
col3 |
col4 |
1 |
a |
x1 |
asdc |
2 |
b |
x2 |
czxa |
3 |
c |
x3 |
xfsdaa |
null |
l |
x56 |
null |
null |
q |
x99 |
null |