没有明确列出列名称的SQL Union NULL列

时间:2019-04-25 15:48:47

标签: sql hive impala

我有两个非常宽的表(30列),但具有非常相似的架构(两个表共享20多个列)。我想将这两个表合并在一起,但希望新表具有两个表中的所有字段。

类似于this Stackoverflow question中的想法。

但是,当我开始编写查询时,我必须指定每个表中的所有列,不仅要做到这一点,而且还要使用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
    ...

来自table2

随着列数的增加,此查询会变得很长,而且对于架构更改也不是很可靠。有没有更好的方法来合并两个为不存在的表自动填充NULL的表?

我正在使用Impala / Hive,但是如果有ANSI方式可以做到这一点,那就太好了!

2 个答案:

答案 0 :(得分:1)

FWIW,SQL UNION将按顺序位置而不是名称匹配列。如果两个SELECT中的列名称相同,则该名称也是结果列的名称。如果不是,则结果的列名称为“实现定义”。

所有这些的含义/后果是您有责任注意 两者 SELECT中列的顺序 以及 这些列的相同命名(如果您希望通过使用名称而不是列号来后续引用UNION结果中的那些列)。

这就是标准要求兼容的实现的行为,因此您几乎没有机会找到可以减轻这种麻烦的实现。

答案 1 :(得分:0)

来自Wikipedia(重点是我):

  

在SQL中,UNION子句将两个SQL查询的结果合并到所有匹配行的单个表中。这两个查询必须得出相同数量的列和兼容的数据类型,以便统一。

因此,简而言之,您必须为不适用的列指定NULL。您可以编写一些脚本来生成SQL,或使用同一列(另一列指示它是哪个属性),但是您有一定的局限性。

不熟悉Hive / Impala,那里可能会有更好的选择。

对于价值而言,here's the MySQL reference page代表UNION。有趣的是,它没有明确指出需要相同数量的列(尽管可能只是因为已假定)。

正如@AlexM所指出的,SELECT *是一个选项。但是,您需要注意这一点,因为列的顺序可能会更改,或者可能会添加新的列,这会中断UNION查询(禁止使用SELECT *的标准警告)。