使用Scala-Spark动态选择带参数的列

使用Scala-Spark动态选择带参数的列,scala,apache-spark,apache-spark-sql,databricks,azure-databricks,Scala,Apache Spark,Apache Spark Sql,Databricks,Azure Databricks,我需要从我要加入的两个表中动态选择列。将要选择的列之一的名称传递给变量。以下是详细信息 表名被传递给变量。连接id和连接类型也是如此 //Creating scala variables for each table var table_name_a = dbutils.widgets.get("table_name_a") var table_name_b = dbutils.widgets.get("table_name_b") //Create scala variable for Jo

我需要从我要加入的两个表中动态选择列。将要选择的列之一的名称传递给变量。以下是详细信息

表名被传递给变量。连接id和连接类型也是如此

//Creating scala variables for each table
var table_name_a = dbutils.widgets.get("table_name_a")
var table_name_b = dbutils.widgets.get("table_name_b")

//Create scala variable for Join Id
var join_id = dbutils.widgets.get("table_name_b") + "Id"

// Define join type
var join_type = dbutils.widgets.get("join_type")
然后,我加入表格。我想从表A中选择所有列,从表B中只选择两列:不管在上面的参数中传递了什么表B,其中一列称为“Description”;第二列与表B同名,例如,如果表B的名称为Employee,我想从表B中选择一个名为“Employee”的列。下面的代码选择表a中的所有列和表B中的描述列(别名)。但是我仍然需要从表B中选择另一个与表同名的列。我事先不知道表B总共有多少列,也不知道列顺序或它们的名称,因为表B是作为参数传递的

// Joining Tables
var df_joined_tables = df_a
                                     .join(df_b,                                               
                                               df_a(join_id)===df_b(join_id),
                                              join_type
                                          ).select($"df_a.*",$"df_b.Description".alias(table_name_b + " Description"))
我的问题是:如何将变量表\u name\u b作为我试图从表b中选择的列传递?

我尝试了下面的代码,这显然是错误的,因为在“$”df_b.table_name_b”中,“table_name_b”应该是参数的内容,而不是列本身的名称

var df_joined_tables = df_a
                                     .join(df_b,                                               
                                               df_a(join_id)===df_b(join_id),
                                              join_type
                                          ).select($"df_a.*",$"df_b.Description".alias(table_name_b + " Description"),$"df_b.table_name_b")
然后我尝试了下面的代码,它给出了错误:“value table_name_b不是org.apache.spark.sql.DataFrame的成员”


如何将变量表\u name\u b作为需要从表b中选择的列传递?

您可以构建一个
列表[org.apache.spark.sql.column]
并在
选择
函数中使用它,如以下示例所示:

//示例输入:
val df=Seq(
(“A”、1、6、7),
(“B”、2、7、6),
(“C”、3、8、5),
(“D”、4、9、4),
(“E”、5、8、3)
).toDF(“名称”、“col1”、“col2”、“col3”)
df.printSchema()
val columnNames=List(“col1”、“col2”)//从参数中选择字符串列名
val columnsToSelect=columnNames.map(col())//将所需的列名从字符串转换为列类型
df.select(columnsToSelect:*).show()//使用列列表
//输出:
+----+----+
|col1 | col2|
+----+----+
|   1|   6|
|   2|   7|
|   3|   8|
|   4|   9|
|   5|   8|
+----+----+
类似地,也可以应用于
连接

更新

添加另一个示例:

val aliasTableA=“tableA”
val aliasTableB=“tableB”
val joinField=“名称”
val df1=序列(
(“A”、1、6、7),
(“B”、2、7、6),
(“C”、3、8、5),
(“D”、4、9、4),
(“E”、5、8、3)
).toDF(“名称”、“col1”、“col2”、“col3”)
val df2=序列(
(“A”、11、61、71),
(“B”、21、71、61),
(“C”、31、81、51)
).toDF(“名称”、“第1列”、“第2列”、“第3列”)
df1.别名(别名表A)
.join(df2.alias(aliasTableB),Seq(joinField))
.selectExpr(s“${aliasTableA}.*”、s“${aliasTableB}.col_1”、s“${aliasTableB}.col_2”).show()
//输出:
+----+----+----+----+-----+-----+
|名称| col1 | col2 | col3 | colu 1 | colu 2|
+----+----+----+----+-----+-----+
|A | 1 | 6 | 7 | 11 | 61|
|B | 2 | 7 | 6 | 21 | 71|
|C | 3 | 8 | 5 | 31 | 81|
+----+----+----+----+-----+-----+

很有趣!但是,我不知道表B作为参数传递后会有多少列。作为表B传递的每个表都可能有不同数量的列,但我事先不知道。我的错误是,我为您的用例添加了一个更好的示例。希望它能帮到您。谢谢!现在有点晚了,我将在周一尝试,让您知道知道:)
val df1=Seq(…).toDF()
是一种以编程方式创建
Dataframe
的方法。在这种情况下,
d1
将是您的
df\u a
(您的数据框架)。在您的问题中,您提到需要从一个表中选择所有列,这是通过
选择expr(s“${aliasTableA}完成的*“
,其中您只需要指定该表的别名。实际上,如果您以与我在示例中添加的方式类似的方式将别名添加到
数据帧中,则当前代码可能会起作用。
var df_joined_tables = df_a
                                     .join(df_b,                                               
                                               df_a(join_id)===df_b(join_id),
                                              join_type
                                          ).select($"df_a.*",$"df_b.Description".alias(table_name_b + " Description"),df_b.table_name_b)