我无法使用 ecto 的 `over/2` 函数在窗口中添加特定的 frame_clause

Posted

技术标签:

【中文标题】我无法使用 ecto 的 `over/2` 函数在窗口中添加特定的 frame_clause【英文标题】:I cannot add a specific frame_clause in a window using ecto's `over/2` function 【发布时间】:2020-04-16 17:10:41 【问题描述】:

我使用 ecto 查询 Postgres 数据库,我需要添加一个 Window 函数来保持累积和。除了所讨论的“金额”的重复值之外,这工作正常,它们被加在一起以获得累积总和。在原始 sql 中,解决方案是添加自定义框架子句 (ROWS UNBOUNDED PRECEDING),但没有明显的方法可以使用查询 DSL 将其添加到 ecto。

在我们的数据库中,我们有多种产品,其中大部分产品都会收到多个带有金额的评级。我需要确定所有评分的总和,还需要确定特定子集中数量的累积总和(与问题无关,仅针对某些上下文)。当前查询的一个例子是:

 from(p in Product,
      left_join: ratings in assoc(p, :ratings),
      select: [
        p.id,
        sum(ratings.amount),
        sum(sum(ratings.amount))
        |> over(
          partition_by: p.selection_0,
          order_by: sum(ratings.amount)
        )
      ],
      group_by: p.id
    )

正如我所说,除了总量相等的产品外,这很好用。这是意料之中的,因为它在原始 postgresql 中的工作方式相同,正如在这个问题中询问和回答的那样:Duplicate lines with postgres window functions

我找不到将 frame_clause 添加到使用 over/2 函数创建的窗口的明显方法。我考虑过使用片段,但期望一个不适用于 frame_clause 的键列表表示法(例如where: fragment("..."))。

【问题讨论】:

【参考方案1】:

看起来你在Elixir Forums 上得到了答案:

from(p in Product,
  left_join: ratings in assoc(p, :ratings),
  select: [
    p.id,
    sum(ratings.amount),
    over(sum(sum(ratings.amount)), :w1)
  ],
  windows: [
    w1: [
      partition_by: p.selection_0,
      order_by: sum(ratings.amount),
      frame: fragment("rows unbounded preceding")
    ]
  ],
  group_by: p.id
)

供参考:https://hexdocs.pm/ecto/Ecto.Query.html#windows/3-frame

【讨论】:

以上是关于我无法使用 ecto 的 `over/2` 函数在窗口中添加特定的 frame_clause的主要内容,如果未能解决你的问题,请参考以下文章

无法混合ecto.create,角色'postgres'不存在[重复]

Ecto.Changeset.cast/4 中没有函数子句匹配

ecto 变更集为现有添加关联

删除 Ecto 中的关联(多对多)

使用 Ecto 2.0.0-rc.0 并执行 ecto.migrate 时出现奇怪的错误

使用动态运算符创建 Ecto 查询