首页 > 解决方案 > hive sql将不同的表连接为结构数组

问题描述

让我们有表header

id |  col1 | col2
1  |  "a" | "b"
2  |  "c" | "d"

和表body

header_id | body_id | body_col
1         | 6       | "abc"
1         | 7       | "def"
2         | 8       | "ghi"
2         | 9       | "jkl"

我想将 body 作为结构数组插入到 header 中,在 json 中,结果如下:

{
  id: 1,
  col1: "a",
  col2: "b",
  body: [{body_id: 6, body_col: "abc"}, {body_id: 7, body_col: "def"}]
},
{
  id: 2,
  col1: "c",
  col2: "d",
  body: [{body_id: 8, body_col: "ghi"}, {body_id: 9, body_col: "jkl"}]
}

我如何实现这一目标?AFAIKcollect_setcollect_list将不起作用,因为它们只将整列收集到一个数组中。

标签: sqlapache-sparkhive

解决方案


您必须首先加入两个数据框。然后collect_list实际上是实现您想要的方式的方法。您只需要在第一个内部绑定body_idbody_col在一起struct

代码如下所示:

val result = header
    .join(body.withColumnRenamed("header_id", "id"), Seq("id"))
    .groupBy("id", "col1", "col2")
    .agg(collect_list(struct('body_id, 'body_col)) as "body")
result.show(false)
+---+----+----+--------------------+
|id |col1|col2|body                |
+---+----+----+--------------------+
|2  |c   |d   |[[8, ghi], [9, jkl]]|
|1  |a   |b   |[[6, abc], [7, def]]|
+---+----+----+--------------------+

我们还可以打印结果的模式,这正是您的 json 的构建方式:

root
 |-- id: string (nullable = true)
 |-- col1: string (nullable = true)
 |-- col2: string (nullable = true)
 |-- body: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- body_id: string (nullable = true)
 |    |    |-- body_col: string (nullable = true)

推荐阅读