在Scala中选择DISTINCT

时间:2013-08-15 16:05:59

标签: 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

这项工作正常,但如果供应商表格中有多个匹配项,它会复制咖啡。

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

理论上你可以做一个:

query.list.distinct

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

query.drop(offset).take(limit).list

因此,简而言之,我需要在我的查询中指定SELECT DISTINCT的方法。

有人有什么想法吗?

4 个答案:

答案 0 :(得分:21)

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

query.groupBy(x=>x).map(_._1)

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

答案 1 :(得分:15)

使用光滑的3.1.0,您可以使用distinctdistinctOn功能(Slick 3.1.0 release notes)。例如:

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)

答案 2 :(得分:5)

我认为这还没有实现。见https://github.com/slick/slick/issues/96

答案 3 :(得分:2)

对于多个栏目上的不同,coffee.name和coffee.price:

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.map(f => (f.name, f.price, f.state)).distinctOn(p => (p._1, p._2)).result)