【问题标题】:Scala slick left join doesnt workScala 光滑的左连接不起作用
【发布时间】:2017-04-23 03:53:21
【问题描述】:

我是 Slick 的新手。

我想从 Echo 表中获取程序_vw 表中不存在的 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)

【问题讨论】:

  • 你能解释一下为什么它不起作用吗?输出是什么?

标签: scala slick slick-3.0


【解决方案1】:

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

但是这种直接的更正是错误的 - 它会产生 子查询 这是不好的。

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

旁注: 请记住,上面的pOption(毕竟是左连接)。

正确的解决方案是这样的:

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 正是你一开始想要的。

【讨论】:

  • 如何运行查询?
  • 谢谢。您的解决方案有效。虽然只有一个变化..我不得不使用 if e.map(_.id).isEmpty 进行过滤。
  • 谢谢。您的解决方案有效。虽然只有一个变化..我不得不使用 if e.map(_.id).isEmpty 进行过滤。
  • 当然,错过了。将您的更正合并到示例中。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-02
  • 1970-01-01
  • 2012-09-10
  • 2019-02-02
相关资源
最近更新 更多