scala - GroupBy 多列作为键并对多列求和,如 sql 吗?

标签 scala group-by

我使用的是 scala 2.12。

我有一个案例类如下:

case class MyClass(date: java.util.Date, book: String, priceLocal: Double, priceConv: Double)

我能够根据日期和预订进行分组。

例如,对于:

val listOfMyClass = List(
  MyClass(20190708, "book1", 100, 120),
  MyClass(20190708, "book1", 200, 220),
  MyClass(20190708, "book2", 50, 60),
  MyClass(20190708, "book2", 60, 70)
)

val groupedData = listOfMyClass.groupBy(t => (t.date, t.book))

我想要像 SQL 中那样的数据:

(20190708, "book1", 300, 340)
(20190708, "book2", 110, 130)

我能够映射并求和一列,但无法使用这两列。

val groupedDataSum = listOfMyClass.groupBy(t => (t.date, t.book)).mapValues(_.map(_.priceLocal).sum)

但是如何将第二列也用作总和?

最佳答案

您可以混合使用 groupBy(按日期和书籍对元素进行分组)和 reduce 来累积分组值:

// val list = List(
//   MyClass(Date(2019, 7, 8), "book1", 100, 120),
//   MyClass(Date(2019, 7, 8), "book1", 200, 220),
//   MyClass(Date(2019, 7, 8), "book2", 50, 60),
//   MyClass(Date(2019, 7, 8), "book2", 60, 70)
// )
list
  .groupBy { case MyClass(date, book, _, _) => (date, book) }
  .mapValues { values =>
    values
      .map { case MyClass(_, _, priceLocal, priceConv) => (priceLocal, priceConv) }
      .reduce((x, y) => (x._1 + y._1, x._2 + y._2))
  }
  .map { case ((date, book), (priceLocal, priceConv)) =>
    (date, book, priceLocal, priceConv)
  }
// List(
//   (Date(2019, 7, 8), "book1", 300, 340),
//   (Date(2019, 7, 8), "book2", 110, 130)
// )

这个:

  • 按日期和书籍对字符进行分组 (groupBy)

  • 通过以下方式映射每个分组值 (mapValues):

    • 将值映射为价格元组
    • 并通过逐个求和来减少这些元组
  • 将元组(日期、书籍)映射到元组(价格、价格)到 4 个元素的元组

关于scala - GroupBy 多列作为键并对多列求和,如 sql 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56941818/

相关文章:

mysql - SQL查询获取两个表中每组的平均值

mysql - 嵌套分组依据

java - 如何使用类型转换从现有列表在 Scala 中创建列表?

Scala - 对重载定义的不明确引用 - 使用可变参数

scala - Array[Byte] hashCode() 在 Scala 中每次返回不同的值

sql - 如何在不分块的情况下按周分组(查询 _trailing_ 4 周)

php - 将 group by 和 min 子句与 inner join 一起使用时数据不一致

mysql - SQL:计算表中不同行值的数量

scala - 使用 spark 在 hive 中流式传输数据存储

scala - 递归遍历 Scala 列表