将数据从源配置单元表的多列复制到目标配置单元表的不同行的单列

Posted

技术标签:

【中文标题】将数据从源配置单元表的多列复制到目标配置单元表的不同行的单列【英文标题】:Copying data from multiple columns of source hive table to single column of target hive table in different rows 【发布时间】:2019-05-29 09:09:45 【问题描述】:

我需要将数据从一个 Hive 源表复制到另一个目标表。下面是带有示例数据的源表结构:

source_table
Userid  Name    Phone1   Phone2  Phone3  Address1   Address2    Address3
123     Jitu    123456   987654  111111  DELHI      GURGAON     NOIDA       
234     Mark    123456   987654  111111  UK         USA         IND

在将数据从源复制到目标时,我的要求是拥有 Phone1、Phone2、Phone3 以及相应的 Address1、Address2 和 Address3 目标表中单个列中的列。下面是数据在目标表中的样子:

Target_table
Userid  Name    Phone_no    Address
123     Jitu    123456      DELHI
123     Jitu    987654      GURGAON
123     Jitu    111111      NOIDA
234     Mark    123456      UK
234     Mark    987654      USA
234     Mark    111111      IND

我知道最简单的方法是为源表中的每个电话和地址列在目标表中进行多次插入 使用 hive 查询语言或 spark 数据框。

有没有其他有效的方法可以实现这一点。

【问题讨论】:

【参考方案1】:

对于每一列索引,可以多次选择原始数据框,然后将选择的数据框通过“union”合并为一个:

val df = Seq(
  (123, "Jitu", "123456", "987654", "111111", "DELHI", "GURGAON", "NOIDA"),
  (234, "Mark", "123456", "987654", "111111", "UK", "USA", "IND")
).toDF(
  "Userid", "Name", "Phone1", "Phone2", "Phone3", "Address1", "Address2", "Address3"
)

val columnIndexes = Seq(1, 2, 3)
val onlyOneIndexDfs = columnIndexes.map(idx =>
  df.select(
    $"Userid",
    $"Name",
    col(s"Phone$idx").alias("Phone_no"),
    col(s"Address$idx").alias("Address")))

val result = onlyOneIndexDfs.reduce(_ union _)

输出:

+------+----+--------+-------+
|Userid|Name|Phone_no|Address|
+------+----+--------+-------+
|123   |Jitu|123456  |DELHI  |
|123   |Jitu|111111  |NOIDA  |
|123   |Jitu|987654  |GURGAON|
|234   |Mark|123456  |UK     |
|234   |Mark|987654  |USA    |
|234   |Mark|111111  |IND    |
+------+----+--------+-------+

【讨论】:

感谢 pasha701,它完全符合我的需要。而且它也非常优化,因为我们直接使用 RDD。 @pasha701.. 能否请您也发布 pyspark 版本? 对不起,我对 Python 不熟悉。在 Scala 中,$"Userid" 表示列“Userid”。 s"Phone$idx" 表示格式化,例如。如果 $idx=1,则为“Phone1”。【参考方案2】:

以防万一,如果您也对 Hive 解决方案感兴趣,横向视图在加入多个数组结果集时会产生笛卡尔积。您可以使用posexplode 获得相同的结果,如下所示:

select Userid,Name,phone,address
from source_table
lateral view posexplode(array(Phone1,Phone2,Phone3))  valphone as x,phone
lateral view posexplode(array(Address1,Address2,Address3)) valaddress as t,address
where x=t
;

hive> set hive.cli.print.header=true;

userid  name    phone   address
123     Jitu    123456  DELHI
123     Jitu    987654  GURGAON
123     Jitu    111111  NOIDA
234     Mark    123456  UK
234     Mark    987654  USA
234     Mark    111111  IND
Time taken: 2.759 seconds, Fetched: 6 row(s)

【讨论】:

以上是关于将数据从源配置单元表的多列复制到目标配置单元表的不同行的单列的主要内容,如果未能解决你的问题,请参考以下文章

如果列数不同,如何处理从源 spark df 到 hive 表的插入

我可以将数据从一个配置单元分区移动到同一张表的另一个分区吗

如何在没有使用“ROW FORMAT DELIMITER”创建配置单元表的情况下将“|”分隔文件加载到配置单元中

创建特定表的转储[重复]

如何将多个表的结果写入配置单元中的单个表?

如何获取/生成现有配置单元表的创建语句?