Scala Slick 过滤器具有两个左连接表的条件
Scala Slick filter with conditions over two left joined tables
我正在尝试在 Slick 中重现此查询。
SELECT *
FROM A
JOIN LEFT B AS B1 ON B1.aId = A.id && B1.condition = 'b1'
JOIN LEFT B AS B2 ON B2.aId = A.id && B2.condition = 'b2'
- (no condition, the query in a plain way)
- WHERE B1.status = 'delete' OR B2.status = 'delete'
- WHERE ((B1.status = 'read' AND B2.status <> 'delete') OR (B1.status <> 'delete' AND B2.status = 'read')
- WHERE B1.status = 'write' AND B2.status = 'write'
- WHERE B1.status = 'full' AND B2.status = 'full'
- WHERE ((B1.status = 'full' AND B2.status = 'write') OR (B1.status = 'write' AND B2.status = 'full')
我不确定这是否可行
到目前为止我有这样的东西
val query = for { ((a, b1Opt), b2Opt) <- ATable.aQuery join
BTable.BQuery on ((joinTable, bTable) => join._1.id === _.AId && bTable.condition === "b1") join
BTable.BQuery on ((joinTable, bTable) => join._1.id === _.AId && bTable.condition === "b2")
} yield (a, b1Opt, b2Opt)
我正在尝试这样的事情
val filterB = query {
case (a, b1Opt, b2Opt) => {
bStatus match {
case "delete" => b1Opt.map(b1 => b1.status === "delete") || b1Opt.map(b2 => b2.status === "delete")
}
}
}
根据您的描述,table B 在 table A 的 id
上的两个连续 left join
应该转换为类似于以下内容:
val joinQuery = for {
((a, b1), b2) <- tableA joinLeft tableB on ( (x, y) =>
x.id === y.aId && y.condition === "b1" )
joinLeft tableB on ( (x, y) =>
x._1.id = y.aId && y.condition === "b2" )
} yield (a, b1, b2)
B1.status = 'delete' and B2.status = 'delete'
的 where
条件应如下所示:
val filterB = joinQuery.filter{ case (_, b1, b2) =>
b1.filter(_.status === "delete").isDefined && b2.filter(_.status === "delete").isDefined
}
请注意,对于 left join
,b1
和 b2
包含在 Option
中,因此 isDefined
用于 [=21] =] 操作.
作为另一个旁注,可能值得考虑在执行left join
s.
我正在尝试在 Slick 中重现此查询。
SELECT *
FROM A
JOIN LEFT B AS B1 ON B1.aId = A.id && B1.condition = 'b1'
JOIN LEFT B AS B2 ON B2.aId = A.id && B2.condition = 'b2'
- (no condition, the query in a plain way)
- WHERE B1.status = 'delete' OR B2.status = 'delete'
- WHERE ((B1.status = 'read' AND B2.status <> 'delete') OR (B1.status <> 'delete' AND B2.status = 'read')
- WHERE B1.status = 'write' AND B2.status = 'write'
- WHERE B1.status = 'full' AND B2.status = 'full'
- WHERE ((B1.status = 'full' AND B2.status = 'write') OR (B1.status = 'write' AND B2.status = 'full')
我不确定这是否可行
到目前为止我有这样的东西
val query = for { ((a, b1Opt), b2Opt) <- ATable.aQuery join
BTable.BQuery on ((joinTable, bTable) => join._1.id === _.AId && bTable.condition === "b1") join
BTable.BQuery on ((joinTable, bTable) => join._1.id === _.AId && bTable.condition === "b2")
} yield (a, b1Opt, b2Opt)
我正在尝试这样的事情
val filterB = query {
case (a, b1Opt, b2Opt) => {
bStatus match {
case "delete" => b1Opt.map(b1 => b1.status === "delete") || b1Opt.map(b2 => b2.status === "delete")
}
}
}
根据您的描述,table B 在 table A 的 id
上的两个连续 left join
应该转换为类似于以下内容:
val joinQuery = for {
((a, b1), b2) <- tableA joinLeft tableB on ( (x, y) =>
x.id === y.aId && y.condition === "b1" )
joinLeft tableB on ( (x, y) =>
x._1.id = y.aId && y.condition === "b2" )
} yield (a, b1, b2)
B1.status = 'delete' and B2.status = 'delete'
的 where
条件应如下所示:
val filterB = joinQuery.filter{ case (_, b1, b2) =>
b1.filter(_.status === "delete").isDefined && b2.filter(_.status === "delete").isDefined
}
请注意,对于 left join
,b1
和 b2
包含在 Option
中,因此 isDefined
用于 [=21] =] 操作.
作为另一个旁注,可能值得考虑在执行left join
s.