在 SparkSQL 中执行 groupBy 和 agg 时包括其他列 [重复]

Posted

技术标签:

【中文标题】在 SparkSQL 中执行 groupBy 和 agg 时包括其他列 [重复]【英文标题】:Include other columns when doing groupBy and agg in SparkSQL [duplicate] 【发布时间】:2018-08-17 12:20:47 【问题描述】:

假设我有一个如下所示的数据集:

+--------------------+---------+------+--------------------+
|             transID|principal|subSeq|          subTransID|
+--------------------+---------+------+--------------------+
|2116e07b-14ea-476...|      bob|     4|ec463751-22ca-477...|
|3859a175-f16b-4fd...|      bob|     4|ec463751-22ca-477...|
|3859a175-f16b-4fd...|      bob|     7|2116e07b-14ea-476...|
+--------------------+---------+------+--------------------+

我想通过基于subSeq 列的最大值聚合列transID 来删除重复行,但我希望结果数据集不显示max(subSeq) 列,而是显示subTransID 列来自原始数据集。

如果我这样做:

dsJoin.groupBy("transID").agg(functions.max("subSeq")).show();

然后我得到

+--------------------+-----------+
|             transID|max(subSeq)|
+--------------------+-----------+
|3859a175-f16b-4fd...|          7|
|2116e07b-14ea-476...|          4|
+--------------------+-----------+

已根据另一行中的最大值 7 正确删除了 subSeq 列中值为 4 的重复行 3859a175-f16b-4fd...。但我希望在结果数据集中显示subTransID 列!

我一定遗漏了一些非常明显的东西。

在 JAVA 中执行此操作。感谢您的任何建议!

【问题讨论】:

【参考方案1】:

您应该将相关属性打包到一个结构中,应用聚合函数,然后再次解压缩该结构((下面的scala代码):

dsJoin.groupBy("transID")
.agg(
     max(struct("subSeq","subTransID")).as("max")
)
.select("transID","max.*")
.show()

【讨论】:

所以 Spark 只在struct 的第一个元素上找到maxstruct 中的其他元素对最大值不起作用? @BjörnJacobs 如果第一个元素相等,那么结构的第二个元素也会起作用【参考方案2】:

agg 表达式中还可以从其他字段中获取first

dsJoin.groupBy("transID").agg(functions.max("subSeq"),functions.first("principal")).show();

【讨论】:

谢谢你,做到了——只是看起来我需要的不是 .first() 而是 .last()?无论如何,这种方式似乎可以做我需要做的事情。 如果“其他”值相同,则使用哪个副本都没有关系 这只有在所有subTransIDtransID 都相同的情况下才有效,我不确定这里是否是这种情况

以上是关于在 SparkSQL 中执行 groupBy 和 agg 时包括其他列 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

SparkSQL大数据实战:揭开Join的神秘面纱

Spark(十八)SparkSQL的自定义函数UDF

group by 子句中的 sparkSQL Map 列

Spark DataFrame 的 groupBy vs groupByKey

Spark学习之路 (十九)SparkSQL的自定义函数UDF

Spark sql分组和总和更改列名?