pab*_*ier 1 append elixir ecto phoenix-framework
我正在尝试使用仅附加语义查询 Ecto 表,因此我想要给定 ID 的完整行的最新版本。这里描述了该技术,但简而言之:我想使用一个获取 ID 的最新时间的子查询来连接一个表本身。在 SQL 中,这看起来像:
SELECT r.*
FROM rules AS r
JOIN (
SELECT id, MAX(inserted_at) AS inserted_at FROM rules GROUP BY id
) AS recent_rules
ON (
recent_rules.id = r.id
AND recent_rules.inserted_at = r.inserted_at)
Run Code Online (Sandbox Code Playgroud)
我在 Ecto 中很难表达这一点。我尝试过这样的事情:
maxes =
from(m in Rule,
select: {m.id, max(m.inserted_at)},
group_by: m.id)
from(r in Rule,
join: m in ^maxes, on: r.id == m.id and r.inserted_at == m.inserted_at)
Run Code Online (Sandbox Code Playgroud)
但尝试运行它时,我遇到了限制:
连接中的查询只能有
where查询中的条件
建议maxes一定只是一种SELECT _ FROM _ WHERE形式。
如果我尝试切换maxes并Rule加入:
maxes =
from(m in Rule,
select: {m.id, max(m.inserted_at)},
group_by: m.id)
from(m in maxes,
join: r in Rule, on: r.id == m.id and r.inserted_at == m.inserted_at)
Run Code Online (Sandbox Code Playgroud)
那么我就无法SELECT整行,只是id和MAX(inserted_at)。
有谁知道如何执行此 JOIN?或者在 Ecto 中查询仅追加的更好方法?谢谢
所做的m in ^maxes不是运行子查询,而是运行查询组合(如果在 from 中)或将查询转换为联接(在联接中)。在这两种情况下,您都在更改相同的查询。鉴于您最初的查询,我相信您需要子查询。
另请注意,子查询需要select返回映射,因此我们可以稍后引用这些字段。沿着这些思路的东西应该有效:
maxes =
from(m in Rule,
select: %{id: m.id, inserted_at: max(m.inserted_at)},
group_by: m.id)
from(r in Rule,
join: m in ^subquery(maxes), on: r.id == m.id and r.inserted_at == m.inserted_at)
Run Code Online (Sandbox Code Playgroud)
PS:我已经向 Ecto 提交了一个提交,澄清了像您这样的情况下的错误消息。
invalid query was interpolated in a join.
If you want to pass a query to a join, you must either:
1. Make sure the query only has `where` conditions (which will be converted to ON clauses)
2. Or wrap the query in a subquery by calling subquery(query)
Run Code Online (Sandbox Code Playgroud)