scala - for循环查询中的外连接?
问题描述
我有一个使用Slick的相当复杂的查询,它涉及大量的连接,使用for
-comprehension来编写它似乎更优雅。
我知道如果所有连接都是内部连接,这是可能的。例如:
val query = TableA
.join(TableB)
.on(_.tableBId === _.id) // Result is an (a, b) tuple.
.join(TableC)
.on(_._1.tableCId === _.id) // Result is an ((a, b), c) tuple.
.join(TableD)
.on(_._1._1.tableDId === _.id) // Result is an (((a, b), c), d) tuple.
.map {
case (((a, b), c), d) => (a, b, c, d)
}
可以重写为更加优雅和易于理解的(恕我直言):
val query = for {
a <- TableA
b <- TableB
if(a.tableBId === b.id)
c <- TableC
if(a.tableCId === c.id)
d <- TableD
if(a.tableDId === d.id)
} yield(a, b, c, d)
如果涉及更多连接,后一种变体也可以很好地扩展。
但是,我不确定如果任何连接是左外连接,这是否可能。假设该TableA.tableDId
字段是一个Option[Int]
值,而不是一个Int
值,因此原始查询现在看起来像这样:
val query = TableA
.join(TableB)
.on(_.tableBId === _.id) // Result is an (a, b) tuple.
.join(TableC)
.on(_._1.tableCId === _.id) // Result is an ((a, b), c) tuple.
.leftJoin(TableD)
.on(_._1._1.tableDId === _.id) // Result is an (((a, b), c), Option[d]) tuple.
.map {
case (((a, b), c), od) => (a, b, c, od)
}
我怎么能把这个写成for
理解?
更新:我在这里Slick outer join with multiple tables上看到了这个问题,但答案并不是特别吸引人,而且已经有 7 年历史了。
解决方案
推荐阅读
- r - 将聚合函数的方法输入到相应变量和组的数据集中
- bash - 使用 -c 标志以交互方式执行 bash 代码(使用 |& 和 gnu 屏幕)
- git - 如何确保文件被 git 完全忽略?
- javascript - 如何使用 fetch 将正文发送到 express 应用程序
- c++ - 使用 std::atomic
作为栅栏 - python - 使用 Python 从 CSV 文件中读取和使用单元格值
- javascript - 在 JavaScript 中写 (a&b)<<1 而不是 (a&b)*2 更传统吗?
- javascript - 根据版本号排序表
- google-maps - 无法从方法中获取对作用域变量的引用
- python - 正则表达式严格匹配具有不同结尾的两行