我是Slick的新手。
我想从program_vw表中不存在的Echo表中获取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)
答案 0 :(得分:1)
首先,你做的不是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正是你想要的开头。