将 LEFT JOIN 查询转换为 Ecto

问题描述

我有一些需要迁移到 Ecto 的查询,出于可维护性的原因,我宁愿不只是将它们包装在一个片段中并收工。

它们中有很多 LEFT JOIN,正如我从 this answer 了解到的,认情况下,Ecto 中的 left_join 会执行 LEFT OUTER JOIN。我似乎无法弄清楚如何向 Ecto 指定我想要一个 LEFT INNER JOIN,这是 PostgresqlLEFT JOIN认行为。

一个玩具示例,假设我们数据库中的帖子可以是匿名的,也可以有创建者。我有一个查询获取足够的信息来进行帖子预览,但我只想包含非匿名帖子:

SELECT
  p.id,p.title,p.body,u.name AS creator_name,u.avatar AS creator_avatar,FROM posts p
LEFT JOIN users u ON p.creator_id = u.id;

我会将其翻译成 Ecto 为:

nonanonymous_posts =
  from p in Post,left_join: u in User,on: p.creator_id == u.id,select: [p.id,u.name,u.avatar]

然后Ecto吐了

SELECT
  t0."id",t0."title",t0."body",t1."name" AS creator_name,t1."avatar" AS creator_avatar,FROM "posts" AS t0
LEFT OUTER JOIN "users" as t1 ON t0."creator_id" = t1."id";

这也会回馈匿名帖子。

解决方法

没有LEFT INNER JOIN这样的东西。只有INNER JOINLEFT [OUTER] JOINOUTER 部分是可选的,因为LEFT JOIN 必须是 外连接)。因此,您想要的只是 Ecto 查询中的 :join:inner_join