scala - 如何折叠光滑的列的总和?
问题描述
我有一个专栏:
val a: Rep[Long] = column[Long]("a")
我想总结一下:
val b: Rep[Option[Long]] = a.sum
如果没有行或总和为负,则返回0
,否则返回总和:
val y: Rep[Long] = b.fold(0) { x => if (x < 0) 0 else x }
但是,最后一个fold
不会编译,因为x
它是 aRep[Long]
而不是 a Long
。
有一个 to 的隐式b
转换AnyOptionExtensionMethods[Rep[Option[Long]], Rep[Long]]
。Rep[Long]
这是导致问题的第二种类型参数。我希望它是Long
。明确表示如下:
val c: LongJdbcType = longColumnType
val d: Shape[FlatShapeLevel, Rep[Long], Long, Rep[Long]] = Shape.repColumnShape[Long, FlatShapeLevel](c)
val e: OptionLift[Rep[Long], Rep[Option[Long]]] = OptionLift.repOptionLift[Rep[Long], Long](d)
val f: AnyOptionExtensionMethods[Rep[Option[Long]], Rep[Long]] = anyOptionExtensionMethods[Long, Rep[Long]](b)(e)
我需要的是:
val d2: Shape[FlatShapeLevel, Long, Long, Long] = ???
val e2: OptionLift[Long, Rep[Option[Long]]] = OptionLift.anyOptionLift[Long, Long](d2)
val f2: AnyOptionExtensionMethods[Rep[Option[Long]], Long] = anyOptionExtensionMethods[Long, Long](b)(e2)
应该是什么d2
?Shape.primitiveShape
是我所期望的,但需要有一个OptionLift.constOptionLift
功能。所以现在我坚持:
val d3: Shape[FlatShapeLevel, Long, Long, ConstColumn[Long]] = Shape.primitiveShape[Long, FlatShapeLevel]
val e3: OptionLift[Long, Rep[Option[Long]]] = ???
val f3: AnyOptionExtensionMethods[Rep[Option[Long]], Long] = anyOptionExtensionMethods[Long, Long](b)(e3)
在我进一步深入兔子洞之前,这应该如何工作?
我很确定我的预期用途fold
是有效的。至少这符合我的直觉以及文档:
/** Extension methods for Options of single- and multi-column values */
final class AnyOptionExtensionMethods[O <: Rep[_], P](val r: O) extends AnyVal {
/** Apply `f` to the value inside this Option, if it is non-empty, otherwise return `ifEmpty`. */
def fold[B, BP](ifEmpty: B)(f: P => B)(implicit shape: Shape[FlatShapeLevel, B, _, BP]): BP = {
...
更新:
可能有一个线索,getOrElse
因为它正在进行一些铸造恶作剧:
def getOrElse[M, P2 <: P](default: M)(implicit shape: Shape[FlatShapeLevel, M, _, P2], ol: OptionLift[P2, O]): P =
// P2 != P can only happen if M contains plain values, which pack to ConstColumn instead of Rep.
// Both have the same packedShape (RepShape), so we can safely cast here:
fold[P, P](shape.pack(default): P)(identity)(shape.packedShape.asInstanceOf[Shape[FlatShapeLevel, P, _, P]])
...
解决方案
我不清楚你想从折叠中产生什么 SQL。折叠的主体需要是 Slick 可以变成 SQL 的东西。
要处理来自数据库的可选结果,您可以做的是过滤掉不需要的值:
val query: Rep[Int] = table.map(_.number).sum
.filter(_ >= 0)
.getOrElse(0)
这将变成一个 SQL Case 表达式。
或者也许运行这个客户端会更清楚:
val action: DBIO[Int] =
table.map(_.number).sum.result.map { optional =>
// Now in Scala, client side
optional.fold(0)(x => if (x < 0) 0 else x)
}
推荐阅读
- r - 在向量的情况下如何将结果组合为数据框
- class - 我可以将类作为扩展添加到 Kotlin 中的另一个类吗?
- python - Tkinter 抛出奇怪的不完整异常
- python - 如何对列文本的一部分进行排序?
- google-app-engine - 请解释 App Engine Instances 参数
- ios - React Native,将图像存储在用户库中而不压缩
- c# - 将备忘录添加到包库的最简洁方法是什么
- powershell - 如何在 Internet Explorer 上更改选择下拉网页
- android - 删除 imageview 背景颜色
- javascript - 如何获取未在 java 中定义的语言环境 DisplayName