这个问题虽然以前似乎已经回答了,但实际上并不是。所有的转置似乎都与一列有关,并将该列中的数据旋转。我想从一组水平列中创建一个垂直表,例如:-
举个例子:-
MyPrimaryKey | Insurer_Factor_1_Name | Insurer_Factor_1_Value | Insurer_Factor_2_Name | Insurer_Factor_2_Code | Insurer_Factor_2_Value | Insurer_Factor_[n]_Name | Insurer_Factor_[n]_Code | Insurer_Factor_[n]_Value | Insurer_Factor_[n]_Code | Insurer_Factor_[n]_Value | xx六边形abcdef - 1234 abcdef123 | 特殊 | SP1 | 2500 | 的 | AW2 | 3500 | ecetera | 等 | 999999 |
---|
您没有找到它的原因是,没有一个魔术技巧可以将一个"有趣"设计的表移动到一个设计良好的表中。您将不得不手工编写查询代码,要么将行合并到表中,要么选择然后爆炸的数组。
当然,你可能会写一些代码来生成你想要的SQL,但它们真的不是一个很好的功能,神奇地将这个feature
格式转换成基于行的格式。
按偏好排序:
重新考虑发送多个文件的决定:如果你只发送多个文件,听起来会节省很多工作。
修改列模式:在列模式中放入一个分隔符(每4列),允许我们查看行。然后我们可以将文件分成几行。使用分隔符
编写自己的自定义数据源:您可以使用现有的文本作为示例,如何编写自己的文本,将每3列解释为一行。
编写一个自定义UDF,将所有列作为参数并返回一个行数组,然后调用该数组来将它们转换为行。这将是缓慢的,所以我给你作为最后的选择。
***警告这会占用很多内存。对于6000行,它将很慢,并且可能会耗尽内存。如果它工作得很好,但我建议你编写自己的数据源,因为这可能是一个更好/更快的策略。
如果你想用UDF做这件事,并且你只对几行做这件事,你可以这样做:
import org.apache.spark.sql._
import org.apache.spark.sql.types._
import org.apache.spark.sql.functions._
/* spark.sql("select * from info").show();
+----+-------+----+
|type|db_type|info|
+----+-------+----+
| bot| x_bot| x|
| bot| x_bnt| x|
| per| xper| b|
+----+-------+----+ */
val schema = ArrayType(new StructType().add("name","string").add("info","string"))
val myUDF = udf((s: Row) => {
Seq( Row( s.get(0).toString, s.get(1).toString ), Row(s.get(2).toString, s.get(2).toString ) )
},schema)
val records = spark.sql("select * from info");
val arrayRecords = records.select( myUDF(struct(records.columns.map(records(_)) : _*)).alias("Arrays") )
arrayRecords.select( explode(arrayRecords("Arrays")).alias("myCol") )
.select( col("myCol.*").show()
+----+-----+
|name| info|
+----+-----+
| bot|x_bot|
| x| x|
| bot|x_bnt|
| x| x|
| per| xper|
| b| b|
+----+-----+
<<ul>