如何在光滑的Scala中转换NULLIF和合并

如何在光滑的Scala中转换NULLIF和合并,scala,slick,Scala,Slick,在slick中进行聚合除法时,我得到的是零除法错误 SQL: 因此,我在sql中修改了查询,如下所示 SELECT person, COALESCE (SUM(item) / NULLIF(SUM(cash), 0) , 0) as avg, FROM peron_item GROUP by person 如何在Slick中实现同样的效果 我当前流畅的scala代码如下所示 val action = query.groupBy(row => (row.person)).map { cas

在slick中进行聚合除法时,我得到的是零除法错误

SQL:

因此,我在sql中修改了查询,如下所示

SELECT person, COALESCE (SUM(item) / NULLIF(SUM(cash), 0) , 0) as avg, FROM peron_item GROUP by person
如何在Slick中实现同样的效果

我当前流畅的scala代码如下所示

val action = query.groupBy(row => (row.person)).map { case (key, value) =>(key._1, value.map{_.item}.sum / value.map(_.cash).sum,)}.result
val finalResult = session.database.run(action)

如果我没说错,您可以通过实现自己的
coalesce
nullif
函数来转换数据:

def optionalDivide[A](dividend: A, divider: Option[A])
  (divideOp: (A, A) => A): Option[A] = 
  divider.map{ d => divideOp(dividend, d)}

def nullIf[A](actual: A, expected: A): Option[A] =
  Option(actual).filter(_ != expected)

def coalesce[A](values: List[Option[A]], defaultValue: A): A = 
  values.find(_.isDefined).flatten.getOrElse(defaultValue)

val action = query.groupBy(row => (row.person)).map {
  case (key, value) => (key._1,  
    coalesce(
      List(
        optionalDivide(
          value.map{_.item}.sum, 
          nullIf(value.map(_.cash).sum, 0)
        )((x, y) => x / y)
      ), 0
    )
  )
}.result
val finalResult = session.database.run(action)
但有一件事我不明白:为什么要尝试实现sql操作,而不是对数据库正确地使用
query

def optionalDivide[A](dividend: A, divider: Option[A])
  (divideOp: (A, A) => A): Option[A] = 
  divider.map{ d => divideOp(dividend, d)}

def nullIf[A](actual: A, expected: A): Option[A] =
  Option(actual).filter(_ != expected)

def coalesce[A](values: List[Option[A]], defaultValue: A): A = 
  values.find(_.isDefined).flatten.getOrElse(defaultValue)

val action = query.groupBy(row => (row.person)).map {
  case (key, value) => (key._1,  
    coalesce(
      List(
        optionalDivide(
          value.map{_.item}.sum, 
          nullIf(value.map(_.cash).sum, 0)
        )((x, y) => x / y)
      ), 0
    )
  )
}.result
val finalResult = session.database.run(action)