You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spark中按条件将多行合并为单行并计算金额

Spark按借贷标识计算调整后金额并重组DataFrame实现方案

实现思路

核心是利用Spark的分布式分组聚合能力处理每个memo_id的借贷金额,避免低效的循环操作:

  • 将贷方(C)金额转为负数,借方(D)保持正数,求和后直接得到computed_amount
  • 按memo_id和memo_attr_1分组(二者在原始数据中一一对应)
  • 重命名列并整理输出结构

完整Scala实现代码

import org.apache.spark.sql.functions._

def compute(memoData: org.apache.spark.sql.Dataset[org.apache.spark.sql.Row]): org.apache.spark.sql.Dataset[org.apache.spark.sql.Row] = {
  memoData
    // 转换金额:借方金额为正,贷方金额为负
    .withColumn("adjusted_amount", when(col("credit_or_debit") === "D", col("amount")).otherwise(-col("amount")))
    // 按memo_id和memo_attr_1分组,聚合求和得到计算后金额
    .groupBy("memo_id", "memo_attr_1")
    .agg(sum("adjusted_amount").alias("computed_amount"))
    // 根据计算后金额确定借贷标识(正数为借方D,负数为贷方C)
    .withColumn("credit_or_debit", when(col("computed_amount") > 0, "D").otherwise("C"))
    // 重命名memo_id为memo_number
    .withColumnRenamed("memo_id", "memo_number")
    // 调整列顺序与目标结构一致
    .select("memo_number", "computed_amount", "credit_or_debit", "memo_attr_1")
}

代码说明

  1. 金额转换:通过when函数将贷方金额转为负数,确保后续求和逻辑等价于「借方总额 - 贷方总额」
  2. 分组聚合:利用groupBy+sum完成分布式的金额计算,这是Spark最优的批量处理方式,远优于循环单条处理
  3. 借贷标识确定:根据计算后金额的正负判断最终标识,适配所有可能的金额结果(不仅限于示例中的正数场景)
  4. 列调整:重命名列并指定输出顺序,匹配目标DataFrame的结构

结果验证

运行上述compute函数后,输出的computedData将完全匹配目标数据结构:

memo_numbercomputed_amountcredit_or_debitmemo_attr_1
MEM_180DX
MEM_2150DY
MEM_3300DZ

内容的提问来源于stack exchange,提问作者saurabh.kg001

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 02:33:28