问题描述
我有一些需要迁移到 Ecto 的查询,出于可维护性的原因,我宁愿不只是将它们包装在一个片段中并收工。
它们中有很多 LEFT JOIN,正如我从 this answer 了解到的,默认情况下,Ecto 中的 left_join
会执行 LEFT OUTER JOIN
。我似乎无法弄清楚如何向 Ecto 指定我想要一个 LEFT INNER JOIN
,这是 Postgresql 中 LEFT 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 JOIN
和LEFT [OUTER] JOIN
(OUTER
部分是可选的,因为LEFT JOIN
必须是 外连接)。因此,您想要的只是 Ecto 查询中的 :join
或 :inner_join
。