在Scala中选择DISTINCT

nop*_*lay 31 scala slick

我正在使用Slick 1,我必须能够在查询中应用过滤器来查找与相关表中的条件匹配的所有实体.

这个使用Slick文档的例子显示了我想要做的事情(这是一个与我的情况很接近的人为例子).

在这里,我想要西海岸供应商提供的所有咖啡.我只想要咖啡,我只对导航到供应商以应用过滤器感兴趣:

val westCoast = Seq("CA", "OR", "WA")
val implicitInnerJoin = for {
  c <- Coffees
  s <- Suppliers if c.supID === s.id && s.state inSet westCoast
} yield c
Run Code Online (Sandbox Code Playgroud)

这项工作正常,但如果在Suppliers表中有多个匹配项,它将复制咖啡.

明显的解决方法是在普通的SQL中做一个SELECT DISTINCT; 但是,我在这里找不到办法.

你理论上可以做一个:

query.list.distinct
Run Code Online (Sandbox Code Playgroud)

结果已经返回后; 但是,我也实现了PAGING支持,因此一旦已经从数据库返回,您就不希望处理结果.这是分页支持:

query.drop(offset).take(limit).list
Run Code Online (Sandbox Code Playgroud)

所以,简而言之,我需要一种在我的查询中指定SELECT DISTINCT的方法.

有人有主意吗?

Mar*_*nek 21

作为一种解决方法,您可以尝试使用groupBy:

query.groupBy(x=>x).map(_._1)
Run Code Online (Sandbox Code Playgroud)

它应该具有相同的语义,但我不确定性能.


Val*_*kov 17

使用光滑的3.1.0,您可以使用distinctdistinctOn功能(Slick 3.1.0发行说明).例如:

val westCoast = Seq("CA", "OR", "WA")
val implicitInnerJoin = for {
  c <- Coffees
  s <- Suppliers if c.supID === s.id && s.state inSet westCoast
} yield c

db.run(implicitInnerJoin.distinctOn(_.name).result)
Run Code Online (Sandbox Code Playgroud)

  • FWIW,目前似乎有[distinctOn的错误](https://github.com/slick/slick/issues/1712). (3认同)

Eug*_*kov 5

我认为这还没有实现.请参阅https://github.com/slick/slick/issues/96