Ecto JOIN并发症仅用于追加表查询

时间:2019-06-03 13:16:48

标签: append elixir phoenix-framework ecto

我正在尝试使用仅追加语义来查询Ecto表,因此我想要给定ID的完整行的最新版本。该技术是described here,但总而言之:我想通过一个子查询在其自身上联接一个表,该子查询获取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)

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

但是尝试运行此命令,我遇到了一个限制:

  

联接中的查询在查询中只能具有where个条件

建议maxes必须只是一种SELECT _ FROM _ WHERE形式。

如果我尝试在JOIN中切换maxesRule

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)

然后我无法SELECTid整个行{}。

有人知道该如何加入吗?还是在Ecto中查询仅追加的更好方法?谢谢?

1 个答案:

答案 0 :(得分:2)

执行new()不是运行子查询,而是查询组合(如果在from中)或将查询转换为联接(在联接中)。在两种情况下,您都将更改相同的查询。有了您的初始查询,我相信您想要子查询。

还要注意,子查询需要m in ^maxes才能返回地图,因此我们以后可以参考这些字段。遵循以下原则应该可以:

select

PS:我已将对Ecto的提交推送给您,以澄清在您这样的情况下的错误消息。

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)