Я не могу добавить спецификацию c frame_clause в окно с помощью функции ecto `over / 2` - PullRequest
2 голосов
/ 16 апреля 2020

Я использую ecto для запроса к базе данных Postgres, и мне нужно добавить функцию Window, чтобы сохранить накопленную сумму. Это прекрасно работает, за исключением дублирующих значений рассматриваемой суммы, они складываются вместе для накопленной суммы. В raw sql решение состоит в том, чтобы добавить пользовательское предложение frame (ROWS UNBOUNDED PRECEDING), но нет очевидного способа добавить это в ecto, используя запрос DSL.

В нашей базе данных у нас есть несколько продуктов, большинство из которых получают несколько рейтингов с суммой. Мне нужно определить сумму всех рейтингов, а также совокупную сумму суммы в определенном подмножестве c (не относится к проблеме, только для некоторого контекста). Пример текущего запроса:

 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, как его спросили и ответили в этом вопросе: Дубликаты строк с postgres оконными функциями

Я не могу найти очевидный способ добавить frame_clause в окно, созданное с помощью функции over/2. Я думал об использовании фрагментов, но ожидал запись списка ключей (например, where: fragment("...")), которая не применима к frame_clause.

1 Ответ

0 голосов
/ 18 апреля 2020

Похоже, вы получили свой ответ на форумах Elixir :

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 кадра

...