Как объединить два разобранных результата, когда один пуст? - PullRequest
0 голосов
/ 26 мая 2020

env: spark2.4.5

My Spark 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)`;

Обратите внимание, что элементы в массиве имеют тип структуры. Моя цель - выделить отдельные элементы в другом массиве.

Итак, как я могу обработать такой пустой случай? Буду очень признателен, если вы дадите мне какое-нибудь предложение.

1 Ответ

1 голос
/ 26 мая 2020

при расчленении массива с использованием 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()

Ouput-

+---+-------+-------+
|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. Выполнить запрос Union

    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()

Output-

+----+---+
|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)

Полный пример см. - это суть

...