【发布时间】:2019-08-25 14:06:43
【问题描述】:
不知道给这个标题取什么名字,但我很难将原始 SQL 重写为 Rails ActiveRecord 方法。
我想提取所选日期范围内每个月的交易总和(总计)。
注意:需要显示该范围内的所有月份。
为此,我使用generate_series SQL 方法在该范围内生成一系列月份。
我正在编写的方法是在 Query 对象中,该对象具有一个现有关系,该关系是从以前过滤的事务。
我现在的功能:
def group_total_by_months
@relation.joins("RIGHT JOIN generate_series(TIMESTAMP '1-1-2018', TIMESTAMP '1-1-2020', interval '1 month') AS series
ON date_trunc('month', transactions.payment_date) = series")
.group("series")
.select("series AS payment_date, sum(transactions.total) AS total")
end
结果:
#<ActiveRecord::AssociationRelation [#<Transaction id: nil, total: 0.61173e3, payment_date: "2019-06-01 00:00:00">, #<Transaction id: nil, total: 0.364446e4, payment_date: "2019-10-01 00:00:00">, #<Transaction id: nil, total: 0.1625e4, payment_date: "2019-08-01 00:00:00">]>
这是按月计算的总和,但只有交易中存在的月数。为什么?因为生成的 SQL 看起来像这样,并且 FROM 子句来自所有事务,而不是过滤的事务:
SELECT series AS payment_date, sum(transactions.total) AS total FROM \"transactions\"
RIGHT JOIN generate_series(TIMESTAMP '1-1-2018', TIMESTAMP '1-1-2020', interval '1 month') AS series\n ON date_trunc('month', transactions.payment_date) = series
WHERE \"transactions\".\"account_id\" = 1
GROUP BY series
我需要如下所示的 SQL:
WITH filteret_transactions AS (
SELECT * FROM transactions WHERE transactions.account_id = 1
)
SELECT series AS payment_date, sum(filteret_transactions.total) AS total
FROM filteret_transactions
RIGHT JOIN generate_series(TIMESTAMP '1-1-2018', TIMESTAMP '1-1-2020', interval '1 month') AS series
ON date_trunc('month', filteret_transactions.payment_date) = series GROUP BY series
我怎样才能做到这一点?
【问题讨论】:
标签: ruby-on-rails postgresql activerecord ruby-on-rails-5