如何通过在配置单元的分区表中选择另一列来覆盖列值

Posted

技术标签:

【中文标题】如何通过在配置单元的分区表中选择另一列来覆盖列值【英文标题】:How to overwrite columns value by selecting another columns in partition table in hive 【发布时间】:2017-02-09 09:42:30 【问题描述】:

您好,如何通过在 hive 中选择相同的分区表来覆盖列值。

我通过执行以下查询创建了表

CREATE TABLE user (fname string,lname string) partitioned By (day int);

在将数据插入表后,我插入数据。 我执行了如下所示的选择查询:

AA  AA  20170201
BB  BB  20170201
CC  CC  20170201
DD  DD  20170202
EE  EE  20170203

根据我的要求,我想在我的表(用户)中再添加一列,在我添加的以下查询的帮助下。

ALTER TABLE user ADD COLUMNS ( day2 int);

添加列后,我的表格如下所示

AA  AA  NULL    20170201
BB  BB  NULL    20170201
CC  CC  NULL    20170201
DD  DD  NULL    20170202
EE  EE  NULL    20170203

但我想要桌子。

AA  AA  20170201    20170202
BB  BB  20170201    20170202
CC  CC  20170201    20170202
DD  DD  20170202    20170202
EE  EE  20170203    20170203

所以我执行了下面的查询

insert overwrite table user partition (day)
select
    fname,
    lname,
    day as day2,
    case 
        when day <= 20170202 then 20170202
        when day > 20170202 then day
    end as day
from user;

然后我执行了如下选择查询

select * from user;

结果是:

AA  AA  NULL    20170201
BB  BB  NULL    20170201
CC  CC  NULL    20170201
AA  AA  NULL    20170202
BB  BB  NULL    20170202
CC  CC  NULL    20170202
DD  DD  NULL    20170202
EE  EE  NULL    20170203

为什么我得到空值。请让我知道我错过了什么,让我知道如何实现这一点。即

   AA   AA  20170201    20170202
    BB  BB  20170201    20170202
    CC  CC  20170201    20170202
    DD  DD  20170202    20170202
    EE  EE  20170203    20170203

【问题讨论】:

【参考方案1】:

按照分区 Hive 表的行为,HiVE 的架构 定义在分区级别维护。因此较旧的分区可能没有收到架构更新。

详细查询

hive> drop table test_insert;
OK
hive> CREATE TABLE test_insert (fname string,lname string) partitioned By (day int);
OK
hive> insert into test_insert partition (day=20170202) values('f','l');
OK
hive> insert into test_insert partition (day=20170203) values('f','l');
OK
hive> select * from test_insert;
OK
f   l   20170202
f   l   20170203
Time taken: 0.148 seconds, Fetched: 2 row(s)
hive> ALTER TABLE test_insert ADD COLUMNS ( day2 int);
OK
Time taken: 0.193 seconds
hive> select * from test_insert;
OK
   f    l   NULL    20170202
   f    l   NULL    20170203

此时,请注意分区表的架构是在分区级别维护的,它应该遵循分区架构而不是表架构。

请注意此处列中的差异。 ALTER 没有更改现有分区的列定义。

  hive> describe formatted test_insert;
    OK
    # col_name              data_type               comment             

    fname                   string                                      
    lname                   string                                      
    day2                    int                                         

    # Partition Information      
    # col_name              data_type               comment             

    day                     int    

    hive> describe formatted test_insert partition (day=20170202);
    OK
    # col_name              data_type               comment             

    fname                   string                                      
    lname                   string                                      

    # Partition Information      
    # col_name              data_type               comment             

    day                     int                           

已调整您的上述查询以创建新分区,以便将架构从表复制到新创建的分区。

 hive> insert overwrite table test_insert partition (day)
        > select
        >     fname,
        >     lname,
        >     day as day2,
        >     case 
        >         when day <= 20170202 then 19999999
        >         when day > 20170202 then day
        >     end as day
        > from test_insert;


    hive> select * from test_insert;
    OK
    f   l   20170202    19999999
    f   l   NULL    20170202
    f   l   NULL    20170203
    Time taken: 0.224 seconds, Fetched: 3 row(s)

希望这很清楚。! 如果您想更改所有现有分区的架构,请尝试以下命令,然后尝试插入。

ALTER TABLE test_insert  partition(day) ADD COLUMNS ( day2 string);

【讨论】:

以上是关于如何通过在配置单元的分区表中选择另一列来覆盖列值的主要内容,如果未能解决你的问题,请参考以下文章

通过选择 Pandas 中的其他列来更新条件列值

通过迭代另一列来创建一列

如何选择与 PostgreSQL 中另一列的最高值的唯一列值对对应的行?

选择 Handsontable 标题单元格

如何将一列的列值组合到 MySQL 中的另一列中?

Hive查询:根据条件选择一列,另一列值匹配某些特定值,然后将匹配结果创建为新列