首页 > 解决方案 > 当一个为空时如何合并两个爆炸结果?

问题描述

环境:火花2.4.5

我的火花 sql:

SELECT A.*
FROM table_0
    LATERAL VIEW explode(table_0.Array_0) exploded_a_values AS A
UNION
SELECT B.*
FROM table_0
    LATERAL VIEW explode(table_0.Array_1) exploded_a_values AS B

分解结构 A 和 B 具有相同的架构。当其中之一为空时发生错误:

Can only star expand struct data types. Attribute: `ArrayBuffer)`;

请注意,数组中的元素是结构类型。我的目的是在不同的数组中挑选出不同的元素。

那么我该如何处理这样的空案呢?如果您能给我一些建议,我将不胜感激。

标签: apache-sparkapache-spark-sql

解决方案


当您使用 展开数组时explode(table_0.Array_0) exploded_a_values AS A

这里

  • exploded_a_values变成table
  • A成为代表的列exploded column

因此,您不能调用A.*它,但您当然可以调用exploded_a_values.*

因此,您修改后的查询将如下所示 -

1. 读取输入

     val table_0 =  spark.range(1, 5)
      .withColumn("Array_0", array(lit(1), lit(2)))
      .withColumn("Array_1", array(lit(null).cast(IntegerType)))
    table_0.show(false)
    table_0.printSchema()

输出-

+---+-------+-------+
|id |Array_0|Array_1|
+---+-------+-------+
|1  |[1, 2] |[]     |
|2  |[1, 2] |[]     |
|3  |[1, 2] |[]     |
|4  |[1, 2] |[]     |
+---+-------+-------+

root
 |-- id: long (nullable = false)
 |-- Array_0: array (nullable = false)
 |    |-- element: integer (containsNull = false)
 |-- Array_1: array (nullable = false)
 |    |-- element: integer (containsNull = true)

2.运行联合查询

    table_0.createOrReplaceTempView("table_0")

    val processed = spark.sql(
      """
        |SELECT exploded_a_values.*, table_0.id
        |FROM table_0
        |    LATERAL VIEW explode(table_0.Array_0) exploded_a_values AS A
        |UNION
        |SELECT exploded_b_values.*, table_0.id
        |FROM table_0
        |    LATERAL VIEW explode(table_0.Array_1) exploded_b_values AS B
      """.stripMargin)
    processed.show(false)
    processed.printSchema()

输出-

+----+---+
|A   |id |
+----+---+
|2   |2  |
|2   |4  |
|null|2  |
|null|4  |
|1   |1  |
|2   |1  |
|1   |2  |
|1   |3  |
|2   |3  |
|1   |4  |
|null|1  |
|null|3  |
+----+---+

root
 |-- A: integer (nullable = true)
 |-- id: long (nullable = false)

注意:联合只能在具有兼容列类型的表上执行。

Edit-1(根据评论)

试过了Array<struct>,同样的查询对我来说效果很好——结果如下:

+------+---+
|A     |id |
+------+---+
|[a, 2]|1  |
|[a, 2]|2  |
|[a, 2]|4  |
|null  |2  |
|null  |4  |
|[a, 2]|3  |
|null  |1  |
|null  |3  |
+------+---+

root
 |-- A: struct (nullable = true)
 |    |-- f1: string (nullable = false)
 |    |-- f2: integer (nullable = false)
 |-- id: long (nullable = false)

有关完整示例,请参阅 -这个要点


推荐阅读