Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
合并Scala Spark sql模式_Sql_Scala_Apache Spark - Fatal编程技术网

合并Scala Spark sql模式

合并Scala Spark sql模式,sql,scala,apache-spark,Sql,Scala,Apache Spark,我正在尝试合并两个数据帧,并创建一个数据帧,其中一个新列包含另一个数据帧作为数组。有人知道如何在scala中实现这一点吗 //模式1 PRIM_KEY: decimal(20,0) (nullable = true) |-- SOME_DECIMAL: decimal(20,0) (nullable = true) |-- SOME_INTEGER: integer (nullable = true) //模式2 PRIM_KEY: decimal(20,0) (nullable = true

我正在尝试合并两个数据帧,并创建一个数据帧,其中一个新列包含另一个数据帧作为数组。有人知道如何在scala中实现这一点吗

//模式1

PRIM_KEY: decimal(20,0) (nullable = true)
|-- SOME_DECIMAL: decimal(20,0) (nullable = true)
|-- SOME_INTEGER: integer (nullable = true)
//模式2

PRIM_KEY: decimal(20,0) (nullable = true)
|-- COLUMN1: string (nullable = false)
|-- COLUMN2: string (nullable = false)
//结果模式

RIM_KEY: decimal(20,0) (nullable = true)
|-- SOME_DECIMAL: decimal(20,0) (nullable = true)
|-- SOME_INTEGER: integer (nullable = true)
|-- an_array: array (nullable = true)
|    |-- element: String (containsNull = false)

一种方法是创建一个将两个列表合并为一个的
UDF
,对连接的数据帧执行
groupBy
,并应用
UDF
,如下所示:

val df1 = Seq(
  (1, 100.1, 10),
  (2, 200.2, 20)
).toDF("pk", "col1", "col2")

val df2 = Seq(
  (1, "a1", "b1"),
  (1, "c1", "d1"),
  (2, "a2", "b2")
).toDF("pk", "str_col1", "str_col2")

def combineLists = udf(
  (a: Seq[String], b: Seq[String]) => a ++ b
)

val df3 = df1.join(df2, Seq("pk")).
  groupBy(df1("pk"), df1("col1"), df1("col2")).agg(
    combineLists(collect_list(df2("str_col1")), collect_list(df2("str_col2"))).alias("arr_col")
  ).
  select(df1("pk"), df1("col1"), df1("col2"), col("arr_col"))

df3.show
+---+-----+----+----------------+
| pk| col1|col2|         arr_col|
+---+-----+----+----------------+
|  1|100.1|  10|[c1, a1, d1, b1]|
|  2|200.2|  20|        [a2, b2]|
+---+-----+----+----------------+

一种方法是创建一个将两个列表合并为一个的
UDF
,对连接的数据帧执行
groupBy
,并应用
UDF
,如下所示:

val df1 = Seq(
  (1, 100.1, 10),
  (2, 200.2, 20)
).toDF("pk", "col1", "col2")

val df2 = Seq(
  (1, "a1", "b1"),
  (1, "c1", "d1"),
  (2, "a2", "b2")
).toDF("pk", "str_col1", "str_col2")

def combineLists = udf(
  (a: Seq[String], b: Seq[String]) => a ++ b
)

val df3 = df1.join(df2, Seq("pk")).
  groupBy(df1("pk"), df1("col1"), df1("col2")).agg(
    combineLists(collect_list(df2("str_col1")), collect_list(df2("str_col2"))).alias("arr_col")
  ).
  select(df1("pk"), df1("col1"), df1("col2"), col("arr_col"))

df3.show
+---+-----+----+----------------+
| pk| col1|col2|         arr_col|
+---+-----+----+----------------+
|  1|100.1|  10|[c1, a1, d1, b1]|
|  2|200.2|  20|        [a2, b2]|
+---+-----+----+----------------+

您寻求的结果是:

RIM_KEY: decimal(20,0) (nullable = true)
|-- SOME_DECIMAL: decimal(20,0) (nullable = true)
|-- SOME_INTEGER: integer (nullable = true)
|-- an_array: array (nullable = true)
|    |-- element: String (containsNull = false)
让我先告诉你:

数组(nullable=true)不是数据类型,而是数据结构。 所以您根本不能将模式定义为数据类型数组

一种方法是使用concat_ws连接字符串,并对第二个数据集执行withcolumn操作

例如:

我不明白使用数组类型作为模式的用例是什么,但是您可以使用连接的结果并转换为数组


希望这对你有帮助,我知道我在这里回答有点晚,但即使现在对你有帮助,我还是会很高兴的。

你正在寻求的结果:

RIM_KEY: decimal(20,0) (nullable = true)
|-- SOME_DECIMAL: decimal(20,0) (nullable = true)
|-- SOME_INTEGER: integer (nullable = true)
|-- an_array: array (nullable = true)
|    |-- element: String (containsNull = false)
让我先告诉你:

数组(nullable=true)不是数据类型,而是数据结构。 所以您根本不能将模式定义为数据类型数组

一种方法是使用concat_ws连接字符串,并对第二个数据集执行withcolumn操作

例如:

我不明白使用数组类型作为模式的用例是什么,但是您可以使用连接的结果并转换为数组


希望这对您有所帮助,我知道我在这里回答有点晚了,但即使现在对您有所帮助,我还是会很高兴的。

您还可以添加数据帧和预期输出吗您还可以添加数据帧和预期输出吗Hanks Leo!这确实有帮助。这可能是显而易见的,但由于我是scala和spark的新手,这对我来说并不明显。但假设我在df1中有一个结果,但我希望将df2的所有结果作为数组列添加到这一行中。如何更改udf和联接以处理此场景?如果我正确理解您的问题,您可以将
udf
重新定义为
def toArrCol=udf((c0:String,c1:String,c2:String)=>Array(c0,c1,c2))
,其中
c0
表示
df1
中的选定列。请注意,
c0
被强制转换为字符串以与其他参数类型匹配,因为Spark不支持数组[Any]模式。因此,基本上我需要能够将数据帧的结果转换为org.apache.Spark.sql.Column,其中包含一个数组,其中数据帧中的每一行都作为数组中的元素列出。因此,我想你想要的是数据分组。我已经用稍微不同的数据帧内容修改了我的答案,以说明建议的解决方案。谢谢Leo!这确实有帮助。这可能是显而易见的,但由于我是scala和spark的新手,这对我来说并不明显。但假设我在df1中有一个结果,但我希望将df2的所有结果作为数组列添加到这一行中。如何更改udf和联接以处理此场景?如果我正确理解您的问题,您可以将
udf
重新定义为
def toArrCol=udf((c0:String,c1:String,c2:String)=>Array(c0,c1,c2))
,其中
c0
表示
df1
中的选定列。请注意,
c0
被强制转换为字符串以与其他参数类型匹配,因为Spark不支持数组[Any]模式。因此,基本上我需要能够将数据帧的结果转换为org.apache.Spark.sql.Column,其中包含一个数组,其中数据帧中的每一行都作为数组中的元素列出。因此,我想你想要的是数据分组。我已经用稍微不同的数据帧内容修改了我的答案,以说明建议的解决方案。