我有一个表格的例子:

表1:

col 1 col2 col3 col4
1 a x1 asdc
2 b x2 czxa
3 c x3 xfsdaa

表2:

col2 col3
l x56
q x99

我只想收到这样一个最后的连接

col 1 col2 col3 col4
1 a x1 asdc
2 b x2 czxa
3 c x3 xfsdaa
null l x56 null
null q x99 null

如何在RSQL(postgresql based SQL)中实现它?我想从第一个表中 Select 所有列,然后 Select union all,并使用NULL AS col1 [...] NULL AS col4来代替缺失的列,但在实际数据中,我有几十个列,所以代码看起来不太好.

有没有其他方法可以实现它?

推荐答案

如果你不介意对专栏重新排序,你可以得到natural full outer join分:

USING子句是一种速记,它允许您利用联接双方对联接列使用相同名称的特定情况(S).它接受一个以逗号分隔的共享列名列表,并形成一个联接条件,其中包括每个列名的相等比较.例如,将T1T2USING (a, b)连接会产生连接条件ON T1.a = T2.a AND T1.b = T2.b.

NATURALUSING的简写形式:它形成了一个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

Sql相关问答推荐

帮助修复查询以识别SQL DW中数据中的递归关系

PostgreSQL:如果发现多行具有相似列值,则跳过 Select 行

使用`lag()`获取上一个时间戳

Redshift PL/pgSQL循环中的参数化列名

缺少日期标识

如何在SQL中从多个查询进行分组

从单个表达式中的分隔字符串中取平均值

计算不同模式的时间跨度

列(值不为空)到其他有序列

如何将 START 和 END 日期之间的日期差异作为 SQL 中的单独列获取

Clickhouse:左连接表到外部数组

SQL Server中使用min()和max()从选定的特定值id表中删除不必要的时间

删除重复记录但保留最新的SQL查询

SQL - 只需要 GROUP BY SELECT 的一列

计算 SQL 中的总体成功率:递归 CTE 还是替代方法?

在 MS Access 中连接相关记录

如何从 2 个 SQLite 表构建嵌套对象?

为每组填写行以进行旋转

SQL 计数和过滤查询优化

在 PostgreSQL 中,如何将数组中的每个元素用作另一个表中的键?