Scala光滑的左连接不起作用

时间:2016-12-08 01:43:36

标签: scala slick slick-3.0

我是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)

1 个答案:

答案 0 :(得分:1)

首先,你做的不是LEFT JOIN(我说的是Slick版本)。为了生成它,您需要使用joinLeft方法。

然而,这种直截了当的修正是错误的 - 它会产生子查询,这是不好的。

for {
      (_, p) <- echoQuery.filter(_.id.isEmpty)
               .joinLeft(programsVwQuery).on(_.id === _.id)
} yield (p.map(_.id))

旁注: 请注意,上面的pOption(毕竟它是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正是你想要的开头。