2013-08-15 13 views
27

私はSlick 1を使用しています。クエリにフィルタを適用して、関連するテーブルの条件に一致するすべてのエンティティを参照できるようにする必要があります。スラックのSELECT DISTINCT

この例では、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を指定する方法が必要になり:ここでページングのサポートです。

誰もが考えている?

答えて

17

はGROUPBYを使用しようとすることができます参照してください。

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

それは明確なものと同じ意味を持っている必要がありますが、私は、パフォーマンスについてはよく分かりません。

+0

ねえ、この1つは働きました!私はなぜ、私は深いダイビングをもっとしなかったのか正確には分かっていませんが、私は迅速な修正が必要でした。 – noplay

+0

なんらかの理由で、これは 'ClassCastException'がスローされた' XxxRow'エンティティの代わりに 'scala.TupleN'を返します。 –

+0

これは原因のようです:https://github.com/slick/slick/pull/735 –

5

これはまだ実装されていないと思います。あなたの周りの仕事としてhttps://github.com/slick/slick/issues/96

+0

は幸いにも、それが行わ&2015年9月4日に合併しました:) –

13

slick 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) 
+1

FWIW、現時点では[distinctOnのバグ](https://github.com/slick/slick/issues/1712)があるようです。 – Nick

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) 
+0

あなたが記述した**特定の注文**である必要があります。つまり、 'map(a =>(a.id、a.name))。disctinctOn(a =>(a._1、a._2))'または「滑らかなキーが見つかりません:s2」ランタイム例外を取得します。 'distinctOn(a =>(a.id、a.name))'を実行すると動作しません –