【发布时间】:2023-04-03 12:59:01
【问题描述】:
我有两个表(表 A 和表 B)。
这些有不同数量的列 - 假设表 A 有更多列。
如何合并这两个表并为表 B 没有的列获取 null?
【问题讨论】:
-
@LukasEder 请发帖this great answer 不在这里真是太好了:)
我有两个表(表 A 和表 B)。
这些有不同数量的列 - 假设表 A 有更多列。
如何合并这两个表并为表 B 没有的列获取 null?
【问题讨论】:
为具有较少列的表添加额外的列作为空
Select Col1, Col2, Col3, Col4, Col5 from Table1
Union
Select Col1, Col2, Col3, Null as Col4, Null as Col5 from Table2
【讨论】:
Select Col1, Col2, Col3, Null as Col4, Null as Col5 from Table2,也可以使用Select *, Null as Col4, Null as Col5 from Table2。
我来到这里并遵循上述答案。但是数据类型的顺序不匹配导致了错误。下面来自另一个答案的描述会派上用场。
上面的结果和你表中的列顺序一样吗?因为 oracle 在列顺序上很严格。下面这个例子产生了一个错误:
create table test1_1790 (
col_a varchar2(30),
col_b number,
col_c date);
create table test2_1790 (
col_a varchar2(30),
col_c date,
col_b number);
select * from test1_1790
union all
select * from test2_1790;
ORA-01790:表达式必须与对应的表达式具有相同的数据类型
正如您所见,错误的根本原因在于使用 * 作为列列表说明符所暗示的列顺序不匹配。通过显式输入列列表可以轻松避免此类错误:
从 test1_1790 中选择 col_a、col_b、col_c 联合所有 从 test2_1790 中选择 col_a、col_b、col_c; 此错误更常见的情况是您无意中交换(或移动)了 SELECT 列表中的两个或更多列:
select col_a, col_b, col_c from test1_1790
union all
select col_a, col_c, col_b from test2_1790;
或者如果上述方法不能解决您的问题,如何在这样的列中创建别名:(查询与您的不同,但这里的重点是如何在列。)
SELECT id_table_a,
desc_table_a,
table_b.id_user as iUserID,
table_c.field as iField
UNION
SELECT id_table_a,
desc_table_a,
table_c.id_user as iUserID,
table_c.field as iField
【讨论】:
对于任何额外的列,如果没有映射,则将其映射为 null,如下面的 SQL 查询
Select Col1, Col2, Col3, Col4, Col5 from Table1
Union
Select Col1, Col2, Col3, Null as Col4, Null as Col5 from Table2````
【讨论】:
通常,当您使用基于集合的运算符时,您需要拥有相同数量的列,因此Kangkan's answer 是正确的。
SAS SQL 有特定的运算符来处理这种情况:
SAS(R) 9.3 SQL Procedure User's Guide
对应(CORR)关键字
CORRESPONDING 关键字仅在指定集合运算符时使用。 CORR 导致 PROC SQL 按名称而不是按序号位置匹配表表达式中的列。名称不匹配的列将从结果表中排除,OUTER UNION 运算符除外。
SELECT * FROM tabA
OUTER UNION CORR
SELECT * FROM tabB;
为:
+---+---+
| a | b |
+---+---+
| 1 | X |
| 2 | Y |
+---+---+
OUTER UNION CORR
+---+---+
| b | d |
+---+---+
| U | 1 |
+---+---+
<=>
+----+----+---+
| a | b | d |
+----+----+---+
| 1 | X | |
| 2 | Y | |
| | U | 1 |
+----+----+---+
U-SQL 支持类似的概念:
外层
需要 BY NAME 子句和 ON 列表。与其他集合表达式相反,OUTER UNION 的输出模式包括来自双方的匹配列和非匹配列。这会产生一种情况,即来自一侧的每一行都有“缺失的列”,这些“缺失的列”仅存在于另一侧。对于此类列,为“缺失的单元格”提供默认值。可空类型的默认值为 null,非可空类型的默认值为 .Net(例如,0 表示 int)。
按姓名
与 OUTER 一起使用时是必需的。该子句表明联合不是根据位置而是根据列的名称来匹配值。如果未指定 BY NAME 子句,则按位置进行匹配。
如果 ON 子句包含“*”符号(它可以被指定为列表的最后一个或唯一的成员),则允许在 ON 子句之外的额外名称匹配,并且结果的列包括所有匹配列按它们在左参数中出现的顺序。
和代码:
@result =
SELECT * FROM @left
OUTER UNION BY NAME ON (*)
SELECT * FROM @right;
编辑:
KQL支持外联合的概念:
种类:
inner - 结果包含所有输入表共有的列子集。
outer - 结果包含任何输入中出现的所有列。未由输入行定义的单元格设置为 null。
例子:
let t1 = datatable(col1:long, col2:string)
[1, "a",
2, "b",
3, "c"];
let t2 = datatable(col3:long)
[1,3];
t1 | union kind=outer t2;
输出:
+------+------+------+
| col1 | col2 | col3 |
+------+------+------+
| 1 | a | |
| 2 | b | |
| 3 | c | |
| | | 1 |
| | | 3 |
+------+------+------+
【讨论】:
如果只有1行,可以使用join
Select t1.Col1, t1.Col2, t1.Col3, t2.Col4, t2.Col5 from Table1 t1 join Table2 t2;
【讨论】: