在 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
的第一个元素上找到max
而struct
中的其他元素对最大值不起作用?
@BjörnJacobs 如果第一个元素相等,那么结构的第二个元素也会起作用【参考方案2】:
在agg
表达式中还可以从其他字段中获取first
dsJoin.groupBy("transID").agg(functions.max("subSeq"),functions.first("principal")).show();
【讨论】:
谢谢你,做到了——只是看起来我需要的不是 .first() 而是 .last()?无论如何,这种方式似乎可以做我需要做的事情。 如果“其他”值相同,则使用哪个副本都没有关系 这只有在所有subTransID
和transID
都相同的情况下才有效,我不确定这里是否是这种情况以上是关于在 SparkSQL 中执行 groupBy 和 agg 时包括其他列 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
Spark DataFrame 的 groupBy vs groupByKey