繁体   English   中英

事件范围超过一个月时,按月累计事件成本(在rails 3中)

[英]Aggregate Event cost by month when Event ranges more than one month (in rails 3)

我有这个Event模型

class Event < ActiveRecord::Base
  attr_accessible :starts_at, :ends_at, :price
end

一个Event可以是一个即时事件:

Event.create(:starts_at => Date.today, :ends_at=>nil, :price => 10.0)

它也可以跨越多天或几个月:

Event.create(:starts_at => Date.today, :ends_at => (Date.today + 2.months), :price => 20.0)

我希望将事件的成本按月分解,以便即时事件的成本自然地落入其所属的月份,并且跨越多个月的事件的成本应该在这些月份之间按比例分配。

显然使用SQL会很难处理,但也许有人对此有一些建议?

计算此聚合的最有效方法是什么?

更新:

这是一个明确定义的sqlfiddle数据结构: http ://sqlfiddle.com/#!12 / a532e / 6

我想从这个数据集中得到的是:

( (Date('2013-01-01'), 31.6), (Date('2013-02-01'), 8.4) )
SELECT event_id
      ,date_trunc('month', day)::date AS month
      ,sum(daily) AS price_this_month
FROM  (
   SELECT event_id
         ,generate_series(starts_at
                         ,COALESCE(ends_at, starts_at)
                         ,interval '1 day') AS day
         ,price / COALESCE((ends_at - starts_at) + 1, 1) AS daily
   FROM   events
   ) a
GROUP  BY 1,2
ORDER  BY 1,2;

- > sqlfiddle

我为PostgreSQL提供了一个更新的sqlfiddle。 你的原始版似乎适用于MySQL。

技巧是:

  • 使用generate_series()为每个事件每天创建一行。
  • 使用COALESCE来处理NULL值,这似乎是允许的ends_at
  • 通过将price除以starts_atends_at + 1之间的天数来计算daily成本, starts_at ends_at修复。 如果ends_at IS NULL默认为1。
  • 每个事件和月份重新聚合。

瞧。

您甚至可以获得每月的确切费率,具体取决于每月的天数。 2月(28天)比1月(31天)便宜。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM