apachespark 如何使用sql查询而不是api覆盖列

7z5jn7bk  于 2021-05-15  发布在  Spark
关注(0)|答案(1)|浏览(394)

例如,我有一个表customers,其中有一列
name
和列
last_name
.
我想连接这两列并覆盖该列
name
与串联的结果。
在spark sql api中,我们可以执行以下操作:

customers.withColumn("name", concat(col("name"), lit(" "), col("last_name")))

在sql查询中执行以下操作:

select *, concat(name, " ", last_name) AS name from customers

而是在 Dataframe 中添加另一个列名。所以最后有两列同名
name
.
sql查询中有没有一种方法可以覆盖现有列而不添加新列?

2wnc66cl

2wnc66cl1#

两种方法都有效。
使用sql方法是可行的。不要使用

,这将包括旧列,只需
CONCAT
并重命名为
AS
.

customers.createOrReplaceTempView("customers")
spark.sql("SELECT CONCAT(name, ' ', last_name) AS name FROM customers").show()
//+--------+
//|    name|
//+--------+
//|John Doe|
//|Jane Doe|
//+--------+

withColumn
同样的,还有一个
withColumnRenamed
.
因此,按照您的意愿执行操作,创建一个新列,然后删除原始列并重命名新列。

// Problem Setup
val customers = = Seq(("John", "Doe"), ("Jane", "Doe")).toDF("name", "last_name")

customers.show()
//+----+---------+
//|name|last_name|
//+----+---------+
//|John|      Doe|
//|Jane|      Doe|
//+----+---------+

import org.apache.spark.sql.functions.{lit, col, concat}

customers.withColumn(
  "name_last_name", concat(col("name"), lit(" "), col("last_name"))
).drop("name", "last_name").withColumnRenamed("name_last_name", "name").show()
//+--------+
//|    name|
//+--------+
//|John Doe|
//|Jane Doe|
//+--------+

当然,你可以继续做手术本身在
withColumn
函数调用,为新生成的列提供标签
name
取代了旧的,但你还是得放弃
last_name
.

customers.withColumn(
  "name", concat(col("name"), lit(" "), col("last_name"))
).drop("last_name").show()
//+--------+
//|    name|
//+--------+
//|John Doe|
//|Jane Doe|
//+--------+

相关问题