与Scala Slick的外部联接

时间:2013-01-17 10:31:31

标签: scala slick

我有两个表,UserUserBusinessPartnerIds

User(id, name, email, whatever)

UserBusinessPartnerIds(userId, bpId)

我正在尝试检索用户和业务伙伴ID列表。

以下查询正常!

database withSession { implicit session: Session =>
      val query = (for {
        (user, userBpid) <- Users leftJoin UserBusinessPartners on (_.id is _.userId)
          if user.email === email &&
             user.password === password &&
             user.active === true &&
             userBpid.dateFrom < today &&
             userBpid.dateTo > today
      } yield (user.id, userBpid.bpId.?))

      val results = query.list

      results.headOption.map( row  => User(row._1, email, password, results.map(_._2).flatten.toSet))
    }

当然,代码的结尾是令人发指的;但是无所谓。

问题是,我希望进行OUTER加入。因此,如果用户没有与另一个表中的业务伙伴ID相对应的行,我仍然希望获得该用户。

有什么想法吗?

编辑 - 编辑问题实际上是正确的。即使他们没有与之关联的业务合作伙伴ID,我仍然希望返回用户

2 个答案:

答案 0 :(得分:1)

嗯,生成的sql是什么样的?应该是左外连接。

我怀疑问题在于:

userBpid.dateFrom < today && userBpid.dateTo > today

由于将条件应用于可能为空的值,因此无法返回用户+ null用户 - 伙伴行;即,当关联的业务伙伴ID行不存在时,它们将永远不会返回true。

作为测试,请执行println(q.sqlStatement)或查看查询日志,并使用和不使用上述查询条件手动运行查询。

修改 没有经过测试,但试试这个,别名用户业务表,一个内部,一个外部。你可能会得到一个非唯一的表别名编译错误,在我以前的尝试中发生了一些外部联接魔法的工作

val q = 
  for{
    (u,upo) <- Users leftJoin UserBusinessPartners on (_.id is _.userId)
      if(u.email is email) && (u.password is password) && (u.active is true)
    up <- UserBusinessPartners
      if(u.id is up.userId) && (up.dateFrom < today) && (up.dateTo > today)
    _ <- Query groupBy(u.id)
  } yield (u.id, upo.bpId.?)

答案 1 :(得分:0)

您需要在加入之前过滤UserBusinessPartners表,这将为您提供没有业务合作伙伴的用户。 类似的东西:

database withSession { implicit session: Session =>
  userBP = UserBusinessPartners.filter(ubp => ubp.dateFrom < today && ubp.dateTo > today)
  val query = (for {
    (user, userbp) <- Users leftJoin userBP on (_.id is _.userId)
      if user.email === email &&
         user.password === password &&
         user.active === true 
  } yield (user.id, userbp.bpId.?))

  val results = query.list

  results.headOption.map( row  => User(row._1, email, password, results.map(_._2).flatten.toSet))
}

过滤器会在桌面上显示仅包含所需业务伙伴的视图,左侧连接将列出所有用户。

您的查询因以下原因失败:

  

userBpid.dateFrom&lt;今天&amp;&amp; userBpid.dateTo&gt;今天

由于上述条件,因为使用null userBpid选择的行将被过滤掉。