好的,我有一个带有列定义和相应顺序位置的表。我正在使用Spark(scala)构建元数据驱动的ETL框架。我有一个包含以下信息的表:
我必须根据该数据构建一个CREATE TABLE语句。没什么大不了的,对吧?我尝试了看似标准的答案:
var metadatadef = spark.sql("SELECT tablename, columnname, datatype, ordinalposition FROM metadata")
.withColumn("columndef", concat($"columnname", lit(" "), $"datatype"))
.sort($"tablename", $"ordinalposition")
.groupBy("tablename")
.agg(concat_ws(", ", collect_list($"columndef")).as("columndefs"))
但是在这里似乎忽略了sort()调用。或在collect_list()和concat_ws()之间重新组合。给定这样的源数据:
+-----------+--------------+---------------+-----------------+
| tablename | columnname | datatype | ordinalposition |
+ ----------+--------------+---------------+-----------------+
| table1 | IntColumn | int | 0 |
| table2 | StringColumn | string | 2 |
| table1 | StringColumn | string | 2 |
| table2 | IntColumn | int | 0 |
| table1 | DecColumn | decimal(15,2) | 1 |
| table2 | DecColumn | decimal(15,2) | 1 |
+-----------+--------------+---------------+-----------------+
我正在尝试获得这样的输出:
+-----------+----------------------------------------------------------------+
| tablename | columndefs |
+-----------+----------------------------------------------------------------+
| table1 | IntColumn int, DecColumn decimal(15,2), StringColumn string |
| table2 | IntColumn int, DecColumn decimal(15,2), StringColumn string |
+-----------+----------------------------------------------------------------+
相反,我想到的是这样的东西:
+-----------+----------------------------------------------------------------+
| tablename | columndefs |
+-----------+----------------------------------------------------------------+
| table1 | IntColumn int, StringColumn string, DecColumn decimal(15,2) |
| table2 | StringColumn string, IntColumn int, DecColumn decimal(15,2) |
+-----------+----------------------------------------------------------------+
我是否需要构建UDF以确保获得正确的订单?我需要将输出最终放在一个数据框中以进行比较,而不仅仅是构建CREATE TABLE语句。
答案 0 :(得分:1)
您可以在{struct
,ordinalposition
)中创建一个columndef
列,并应用sort_array
以在{ {1}}转换如下:
columndef