如何为 Spark SQL 中的posexplode 列提供别名?

Posted

技术标签:

【中文标题】如何为 Spark SQL 中的posexplode 列提供别名?【英文标题】:How to give alias name for posexplode columns in Spark SQL? 【发布时间】:2019-01-22 13:09:40 【问题描述】:

当我在 Spark SQL 中使用 posexplode() 函数时,以下语句会生成“pos”和“col”作为默认名称

scala> spark.sql(""" with t1(select to_date('2019-01-01') first_day) select first_day,date_sub(add_months(first_day,1),1) last_day, posexplode(array(5,6,7)) from t1 """).show(false)
+----------+----------+---+---+
|first_day |last_day  |pos|col|
+----------+----------+---+---+
|2019-01-01|2019-01-31|0  |5  |
|2019-01-01|2019-01-31|1  |6  |
|2019-01-01|2019-01-31|2  |7  |
+----------+----------+---+---+

在 spark.sql 中覆盖这些默认名称的语法是什么? 在数据帧中,这可以通过提供df.explode(select 'arr.as(Seq("arr_val","arr_pos")))

来完成
scala> val arr= Array(5,6,7)
arr: Array[Int] = Array(5, 6, 7)

scala> Seq(("dummy")).toDF("x").select(posexplode(lit(arr)).as(Seq("arr_val","arr_pos"))).show(false)
+-------+-------+
|arr_val|arr_pos|
+-------+-------+
|0      |5      |
|1      |6      |
|2      |7      |
+-------+-------+

如何在 SQL 中得到它?我试过了

spark.sql(""" with t1(select to_date('2011-01-01') first_day) select first_day,date_sub(add_months(first_day,1),1) last_day, posexplode(array(5,6,7)) as(Seq('p','c')) from t1 """).show(false)

spark.sql(""" with t1(select to_date('2011-01-01') first_day) select first_day,date_sub(add_months(first_day,1),1) last_day, posexplode(array(5,6,7)) as(('p','c')) from t1 """).show(false)

但他们正在抛出错误。

【问题讨论】:

【参考方案1】:

您可以使用LATERAL VIEW:

spark.sql("""
  WITH t1 AS (SELECT to_date('2011-01-01') first_day)
  SELECT first_day, date_sub(add_months(first_day,1),1) last_day, p, c
  FROM t1
  LATERAL VIEW  posexplode(array(5,6,7)) AS p, c
""").show
+----------+----------+---+---+
| first_day|  last_day|  p|  c|
+----------+----------+---+---+
|2011-01-01|2011-01-31|  0|  5|
|2011-01-01|2011-01-31|  1|  6|
|2011-01-01|2011-01-31|  2|  7|
+----------+----------+---+---+

或一组别名

spark.sql("""
  WITH t1 AS (SELECT to_date('2011-01-01') first_day)
  SELECT first_day, date_sub(add_months(first_day,1),1) last_day,
         posexplode(array(5,6,7)) AS (p, c) 
  FROM t1 
""").show
+----------+----------+---+---+
| first_day|  last_day|  p|  c|
+----------+----------+---+---+
|2011-01-01|2011-01-31|  0|  5|
|2011-01-01|2011-01-31|  1|  6|
|2011-01-01|2011-01-31|  2|  7|
+----------+----------+---+---+

使用 Spark 2.4.0 测试。

请注意,别名不是字符串,不应使用'" 引用。如果必须使用非标准标识符,则应使用反引号,即

WITH t1 AS (SELECT to_date('2011-01-01') first_day)
SELECT first_day, date_sub(add_months(first_day,1),1) last_day,
       posexplode(array(5,6,7)) AS (`arr pos`, `arr_value`) 
FROM t1 

【讨论】:

以上是关于如何为 Spark SQL 中的posexplode 列提供别名?的主要内容,如果未能解决你的问题,请参考以下文章

Learning Spark [6] - Spark SQL高级函数

如何为 SQL 中的每个特定列应用窗口? [复制]

如何为 spark-csv 提供 parserLib 和 inferSchema 选项

C# SQL:如何为 SQL 表列中的每个不同值启动代码?

Scala Spark,如何为列添加值

Spark Scala - 如何为每个组创建新列,然后在 spark 数据框中分解列值