12

次のようなテーブルがあるとします。

UserActions
    UserId INT
    ActionDate TIMESTAMP
    Description TEXT

ユーザーが特定のアクションを実行した日付を保持します。すべてのユーザーが実行した最後のアクションを取得したい場合は、SQL で次のようにする必要があります。

SELECT *
FROM   UserActions,
       (
           SELECT ua.UserId,
                  max(ua.ActionDate) AS lastActionDate
           FROM   UserActions ua
           GROUP BY ua.UserId
       ) AS lastActionDateWithUserId
WHERE  UserActions.UserId = lastActionDateWithUserId.UserId 
  AND  UserActions.ActionDate = lastActionDateWithUserId.lastActionDate

ここで、次のような UserActions 用に scalaquery 0.9.5 でセットアップされたテーブル構造が既にあるとします。

case class UserAction(userId:Int,actionDate:Timestamp,description:String)

object UserActions extends BasicTable[UserAction]("UserActions"){

    def userId = column[Int]("UserId")

    def actionDate = column[Timestamp]("ActionDate")

    def description  = column[String]("Description")

    def * = userId ~ actionDate ~ description <> (UserAction, UserAction.unapply _)
}

私の質問は: ScalaQuery/SLICK では、どうすればそのようなクエリを実行できますか?

4

1 に答える 1

10

Scala 2.10 で Slick 1.0.0 を使用しました。

オブジェクトを次のように定義しました。

case class UserAction(userId: Int, actionDate: Timestamp, description: String)

object UserActions extends Table[UserAction]("UserActions") {

  def userId = column[Int]("UserId")
  def actionDate = column[Timestamp]("ActionDate")
  def description = column[String]("Description")
  def * = userId ~ actionDate ~ description <> (UserAction, UserAction.unapply _)
}

セッションブロック内

Database.forURL("jdbc:h2:mem:test1", driver = "org.h2.Driver") withSession {
  //...
}

サンプルデータを挿入しました

UserActions.insert(UserAction(10, timeStamp, "Action 1"))
UserActions.insert(UserAction(10, timeStamp, "Action 2"))
UserActions.insert(UserAction(10, timeStamp, "Action 3"))
UserActions.insert(UserAction(20, timeStamp, "Action 1"))
UserActions.insert(UserAction(20, timeStamp, "Action 2"))
UserActions.insert(UserAction(30, timeStamp, "Action 1"))

Query(UserActions).list foreach println

最初に行うことは、最大クエリを作成することです

// group by userId and select the userId and the max of the actionDate
val maxQuery =
  UserActions
    .groupBy { _.userId }
    .map {
      case (userId, ua) =>
        userId -> ua.map(_.actionDate).max
    }

結果のクエリは次のようになります

val result =
  for {
    ua <- UserActions
    m <- maxQuery
    if (ua.userId === m._1 && ua.actionDate === m._2)
  } yield ua

result.list foreach println
于 2013-02-23T15:44:20.110 に答える