我有两个非常宽的表(30列),但模式非常相似(两个表共享20多列)。我想将这两个表合并在一起,但希望新表包含两个表中的所有字段。
类似于这个问题的想法。
但是,当我开始编写查询时,挑战就出现了,我必须指定每个表中的所有列,不仅如此,还要使用null来填充只存在于另一个表中的列。
这样地:
select
commoncolumn1,
commoncolumn2,
table1_only_column1,
NULL as table2_only_column1
...
from table1
union all
select
commoncolumn1,
commoncolumn2,
NULL as table1_only_column1,
table2_only_column1
...
从表2
随着列数的增加,这个查询会变得很长,而且对模式更改也不是很健壮。有没有更好的合并两个表的方法来自动填充不存在的表的空值?
我使用的是IMPA/HIVE,但是如果有ANSI的方式来做,那太好了!
2条答案
按热度按时间rseugnpd1#
fwiw,sql union将按顺序位置匹配列,而不是按名称匹配。如果两个选项中的列名相同,则这也是结果列的名称。如果不是,则结果的列名为“implementation defined”。
所有这一切的意义/后果是,您有责任注意选择中列的顺序以及这些列的相同命名(如果您希望在联合结果中使用名称而不是列号来引用这些列)。
这就是标准所要求的遵从性实现的行为,因此您几乎没有机会找到一个能够减轻这种情况给您带来的痛苦的实现。
e4yzc0pl2#
来自维基百科:
在sql中,union子句将两个sql查询的结果合并到一个包含所有匹配行的表中。这两个查询必须产生相同的列数和兼容的数据类型才能合并。
所以简而言之,你必须指定
NULL
对于不适用的列。您可以编写一些脚本来生成sql,或者使用同一列(另一列指示它是哪个属性),但是您受到了一些限制。不熟悉Hive/ Impala ,那里可能有更好的选择。
值得一提的是,这里有一个mysql参考页
UNION
. 有趣的是,它没有明确指出需要相同数量的列(尽管这可能只是因为它是假定的)。正如@alexm所说,
SELECT *
可能是个选择。但是,您需要注意这一点,因为列的顺序可能会更改,或者可能会添加新的列,这会破坏UNION
查询(禁止使用的标准警告)SELECT *
).