Scala 光滑的左连接不起作用
Scala slick left join doesnt work
我是 Slick 的新手。
我想从 Echo table 中获取不存在于 programs_vw table.
中的 ID 列表
我已经编写了有效的 SQL 查询
SELECT f.`id`
FROM `Full`.`programs_vw` f
LEFT JOIN `FULL`.`Echo` e ON f.`id`=e.`id`
WHERE e.`id` IS NULL
ORDER BY f.`id`;
我参考了 http://slick.lightbend.com/doc/3.0.0/queries.html 中的示例并写了这个但是它不起作用
val query = for {
(t, f) <- echoQuery.filter(_.id.isEmpty) join programsVwQuery on(_.id === _.id)
} yield (f.id)
db.run(query.to[List].result)
首先你所做的不是 LEFT JOIN(我说的是 Slick 版本)。为了生成它,您需要使用 joinLeft
方法。
然而,这种简单的更正是错误的 - 它产生了 子查询,这是不好的。
for {
(_, p) <- echoQuery.filter(_.id.isEmpty)
.joinLeft(programsVwQuery).on(_.id === _.id)
} yield (p.map(_.id))
旁注:
请记住上面的 p
是一个 Option
(毕竟它是 LEFT JOIN)。
更正的解决方案是这样的:
for {
(e, p) <- echoQuery
.joinLeft(programsVwQuery).on(_.id === _.id) if e.id.isEmpty
} yield (p.map(_.id))
我认为这是一个好兆头 - 它实际上读起来几乎像 SQL。
完全正确的解决方案
上面生成了一种你想要的没有子查询的连接,但如果你将它与你想要的查询进行比较,它实际上不会产生你想要的。如果 Slick
通常可以读作 SQL 而不是我们的 SQL 是这样的(您想要的版本):
SELECT f.`id`
FROM `Full`.`programs_vw` f
LEFT JOIN `FULL`.`Echo` e ON f.`id`=e.`id`
WHERE e.`id` IS NULL
ORDER BY f.`id`;
与 Slick 版本的精确映射如下所示:
val query =
(for {
(p, e) <- programsVwQuery
.joinLeft(echoQuery).on(_.id === _.id) if e.map(_.id).isEmpty
} yield (p.id))).sortBy(id => id)
db.run(query.result) // this runs the query
在这种情况下,基本上您完全按照 SQL 进行操作。 它完全符合您想要的查询。如果你看看生成的 SQL 正是你一开始想要的
我是 Slick 的新手。
我想从 Echo table 中获取不存在于 programs_vw table.
中的 ID 列表我已经编写了有效的 SQL 查询
SELECT f.`id`
FROM `Full`.`programs_vw` f
LEFT JOIN `FULL`.`Echo` e ON f.`id`=e.`id`
WHERE e.`id` IS NULL
ORDER BY f.`id`;
我参考了 http://slick.lightbend.com/doc/3.0.0/queries.html 中的示例并写了这个但是它不起作用
val query = for {
(t, f) <- echoQuery.filter(_.id.isEmpty) join programsVwQuery on(_.id === _.id)
} yield (f.id)
db.run(query.to[List].result)
首先你所做的不是 LEFT JOIN(我说的是 Slick 版本)。为了生成它,您需要使用 joinLeft
方法。
然而,这种简单的更正是错误的 - 它产生了 子查询,这是不好的。
for {
(_, p) <- echoQuery.filter(_.id.isEmpty)
.joinLeft(programsVwQuery).on(_.id === _.id)
} yield (p.map(_.id))
旁注:
请记住上面的 p
是一个 Option
(毕竟它是 LEFT JOIN)。
更正的解决方案是这样的:
for {
(e, p) <- echoQuery
.joinLeft(programsVwQuery).on(_.id === _.id) if e.id.isEmpty
} yield (p.map(_.id))
我认为这是一个好兆头 - 它实际上读起来几乎像 SQL。
完全正确的解决方案
上面生成了一种你想要的没有子查询的连接,但如果你将它与你想要的查询进行比较,它实际上不会产生你想要的。如果 Slick
通常可以读作 SQL 而不是我们的 SQL 是这样的(您想要的版本):
SELECT f.`id`
FROM `Full`.`programs_vw` f
LEFT JOIN `FULL`.`Echo` e ON f.`id`=e.`id`
WHERE e.`id` IS NULL
ORDER BY f.`id`;
与 Slick 版本的精确映射如下所示:
val query =
(for {
(p, e) <- programsVwQuery
.joinLeft(echoQuery).on(_.id === _.id) if e.map(_.id).isEmpty
} yield (p.id))).sortBy(id => id)
db.run(query.result) // this runs the query
在这种情况下,基本上您完全按照 SQL 进行操作。 它完全符合您想要的查询。如果你看看生成的 SQL 正是你一开始想要的