web-dev-qa-db-ja.com

スリックで集計する方法

スリックに次のようなクエリを作成させたい

select max(price) from coffees where ... 

しかし slickのドキュメント 役に立たない

val q = Coffees.map(_.price) //this is query Query[Coffees.type, ...]
val q1 = q.min // this is Column[Option[Double]]
val q2 = q.max
val q3 = q.sum
val q4 = q.avg 

これらのq1-q4はクエリではないため、結果を取得することはできませんが、他のクエリ内で使用することはできます。

この文

for {
  coffee <- Coffees
} yield coffee.price.max

正しいクエリを生成しますが、非推奨です(警告を生成します:「クラスColumnExtensionMethodsのメソッドmaxは非推奨です:代わりにQuery.maxを使用してください」)。 警告なしでそのようなクエリを生成する方法は?

もう1つの問題は、groupbyで集計することです。

"select name, max(price) from coffees group by name"

でそれを解決しようとしました

for {
  coffee <- Coffees
} yield (coffee.name, coffee.price.max)).groupBy(x => x._1)

を生成します

select x2.x3, x2.x3, x2.x4 from (select x5."COF_NAME" as x3, max(x5."PRICE") as x4 from "coffees" x5) x2 group by x2.x3

これは明らかなデータベースエラーを引き起こします

column "x5.COF_NAME" must appear in the GROUP BY clause or be used in an aggregate function

そのようなクエリを生成する方法は?

27
Jeriho

私が知る限り、最初のものは単純です

Query(Coffees.map(_.price).max).first

そして2番目のもの

val maxQuery = Coffees
  .groupBy { _.name }
  .map { case (name, c) =>
    name -> c.map(_.price).max
  }

maxQuery.list

または

val maxQuery = for {
  (name, c) <- Coffees groupBy (_.name)
} yield name -> c.map(_.price).max

maxQuery.list
31
EECOLOR