多表的Slick外连接

14

在两个表之间执行外连接很简单:

tblA.leftJoin(tblB).on(_.aId === _.bId)

但是当涉及到5个表之间的连接时,它很快变得难以处理:

tblA.leftJoin(tblB).on(_.aId === _.bId).
    leftJoin(tblC).on(_._1.aId === _.cId).
    leftJoin(tblD).on(_._1._1.aId === _.dId).
    leftJoin(tblE).on(_._1._1._1.aId === _.eId)

元组访问器有点令人困惑,特别是如果它们并不都访问第一个表格的话。

有更好的方法吗?

内连接与使用 filter 的 flatMap 在语义上等价,可以解决内连接的问题:

for {
    a <- tblA
    b <- tblB if a.aId === b.bId
    c <- tblC if a.aId === c.cId
    d <- tblD if a.aId === d.dId
    e <- tblE if a.aId === e.eId
} yield ???

外连接是否有类似优雅的语法?

1个回答

6
这个怎么样?
tblA.leftJoin(tblB).leftJoin(tblC).leftJoin(tblD).leftJoin(tblE).on{
  case ((((a,b),c),d),e) =>
    a.aId === b.bId &&
    a.aId === c.cId &&
    a.aId === d.dId &&
    a.aId === e.eId
}

目前它无法生成最佳SQL,但我们希望很快改进。

使用左连接生成HLists应该可以使模式匹配更好,但可能会受到阻碍: https://github.com/slick/slick/issues/728


1
我尝试了这种方法,但是Slick生成的SQL查询包含一些语法错误,MySQL无法运行它。还有一点需要说明的是,通过其他方式进行多个左连接生成的查询在MySQL上执行非常缓慢。这些问题有解决方案吗? - Aldo Stracquadanio
如果它生成无效的SQL,请确保您使用的是Slick 2.0.1,如果仍然存在问题,请提供重现步骤和生成的无效SQL报告错误。我们知道这个问题,MySQL优化器似乎在子查询方面表现非常糟糕,而Slick在某些情况下会不必要地生成子查询。您尝试过MySQL 5.6吗?优化器有了显著的改进。此外,Slick在这个领域可能会在某个时候得到改进。这里有一种通过手动替换非最优SQL为优化SQL的模式:https://gist.github.com/cvogt/8054159,但需要适应于Slick 2。 - cvogt
我正在使用Slick 2.0.1,而在我们公司中使用的是MySQL 5.5,因此我没有在5.6上尝试过。我将尝试在我们的代码之外重现失败的查询,并在成功后提交一个问题。无论如何,感谢您提供的指引! - Aldo Stracquadanio
使用Slick 2.1.0时,我也遇到了无效的SQL(引用的列不存在)。 (“不会生成最佳SQL”:涉及到派生表,如果手动编写A LEFT JOIN B LEFT JOIN C,则可能不会这样做。) - qu1j0t3
尝试使用3.0版本。Slick 3.1将改善生成的SQL结构。 - cvogt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接