光滑3:计数" OR NULL" with leftJoin和groupBy

时间:2018-01-09 02:22:09

标签: scala slick slick-3.0

我正在创建一个微博系统。像Twitter一样,我想用“(1)Like Count”和“(2)用户是否已经喜欢它来检索帖子数据?”。

我的数据库架构:
post(id:Int,title:String)
favorite(id:Int,post_id:Int,user_id:Int)

我可以在SQL中得到我想要的东西(假设用户的id是1)。

SELECT post.id, post.title, COUNT(favorite.id), COUNT(favorite.user_id = 1 OR NULL) FROM post 
  LEFT JOIN favorite ON post.id = favorite.post_id
  GROUP BY post.id

但是对于Slick 3,我不知道如何在(2)上得到相同的结果。

Post.joinLeft(Fav).on(_.id  === _.postId)
    .groupBy(_._1)
    .map { case (post, group) => (
        post,
        group.map(_._2.map(_.id)).countDefined,  // (1) this works!
        group.map(_._2.???).countDefined   // (2) ?
    )}

我该如何查询?

更新: Sav Schema for Fav专栏(我使用了slick-codegen)

val id: Rep[Int] = column[Int]("id", O.AutoInc, O.PrimaryKey)
val userId: Rep[Int] = column[Int]("user_id")
val postId: Rep[Int] = column[Int]("post_id")

2 个答案:

答案 0 :(得分:0)

我不太确定这是否有用,但我记得做过类似的事情。

您现在可以尝试此操作(假设<p-column field="time" header="Time" [filter]="true" filterPlaceholder="" filterMatchMode="in"> <ng-template pTemplate="filter" let-col> <i class='fa fa-search' (click)='showFilter = !showFilter'></i> <p-multiSelect [hidden]="!showFilter" [options]="timeOptions" styleClass="ui-column-filter" (onChange)="dt.filter($event.value,col.field,col.filterMatchMode)"> </p-multiSelect> </ng-template> </p-column> favourite.user_id),

Column[Option[Int]]

答案 1 :(得分:0)

您可以通过更改以下行来删除 Sarvesh Kumar Singh 的答案中的编译错误(但是您将在光滑的3.1.X和3.2.X上获得运行时错误):

group.filter{
      case (p, f) => f.filter(_.userId === 1).isDefined
    }.length

由于f的类型为Rep[Option[Favorite]],因此您不直接使用f.userId。

注意:当您尝试在groupBy + filter或map之后调用length函数时,该slick会引发运行时错误。您可以在此处跟踪问题 - https://github.com/slick/slick/issues/1355

您可以使用以下代码:

Post.joinLeft(Favorite)
  .on(_.id  === _.postId)
  .groupBy(_._1)
  .map{ case (post, group) => (
    post,
    group.map(_._2.map(_.id)).countDefined,
    group.map(_._2.filter(_.userId === 1).map(_.userId)).countDefined 
    )}