2

我有两张桌子,User并且UserBusinessPartnerIds

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 join。因此,如果用户在另一个表中没有与业务伙伴 ID 对应的行,我仍然想获取该用户。

有任何想法吗?

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

4

2 回答 2

1

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

我怀疑问题出在:

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

由于将条件应用于潜在的空值,因此无法返回用户 + 空用户合作伙伴行;即,当关联的业务伙伴 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.?)
于 2013-01-17T13:37:02.220 回答
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 < 今天 && userBpid.dateTo > 今天

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

于 2015-02-08T11:50:49.537 回答