繁体   English   中英

分组用户 - 按月累计计数

[英]Grouping users - cumulative count by month

我可以在每个月按计数对用户进行分组,如下所示:

User.group('year(created_at)').group('month(created_at)').count
#=> {[2015, 4]=>90, [2015, 5]=>133, [2015, 6]=>131, [2015, 7]=>28, [2015, 8]=>45, [2015, 9]=>6}

我想创建统计数据,显示用户数量增长数月。

所以它会返回这样的东西:

{[2015, 4]=>20, [2015, 5]=>40, [2015, 6]=>55, [2015, 7]=>70, [2015, 8]=>100, [2015, 9]=>130}
# each entry is a year, month and total users count from the beginning of time by the end of this month.

我怎样才能得到想要的结果?

我正在寻找数据库级解决方案(ActiveRecord查询),如果可能的话。

任何建议表示赞赏。

所以,如果我误解了任何事情,请纠正我。 您有几个月的用户注册,即1月份的1个用户,2月份的2个用户和3月份的3个用户,并且您希望构建一个用户增长的图表,因此您希望1月份有1个用户,2月份有3个用户,3月份有6个用户。 如果是这种情况,您可以执行以下操作:

counts = {[2015, 4]=>1, [2015, 5]=>2, [2015, 6]=>3, [2015, 7]=>4, [2015, 8]=>5, [2015, 9]=>6}     

keys = counts.keys # save keys => [[2015, 4], [2015, 5], [2015, 6], [2015, 7], [2015, 8], [2015, 9]]

acc_values = counts.values.dup # .dup is needed if you don't want to spoil original values  
# because of for the following map! operation, 
# right now acc_values returns => [1, 2, 3, 4, 5, 6]

# use map! instead of map so we have access to already changed items, 
# while we iterating over the next
acc_values.map!.with_index { |val, key| key.zero? ? val : acc_values[key - 1] + val }    
# => [1, 3, 6, 10, 15, 21]

# build resulting hash
acc_counts = keys.zip(acc_values).to_h    
# => {[2015, 4]=>1, [2015, 5]=>3, [2015, 6]=>6, [2015, 7]=>10, [2015, 8]=>15, [2015, 9]=>21}

如果g是给定的散列,其中g[[y,m]]y ,月m的新用户数,并且您想要创建一个散列h ,其中h[[y,m]]是累积数量用户在y ,月m ,四舍五入到最接近的5h可以按如下方式计算:

g = {[2015, 4]=>90, [2015, 5]=>133, [2015, 6]=>131, [2015, 7]=>28,
     [2015, 8]=>45, [2015, 9]=>6}

h = g.keys.sort.each_with_object(Hash.new(0)) {|k,h| h[k]=g[k]+ h[previous(k)]}
  #=> {[2015, 4]=>90, [2015, 5]=>223, [2015, 6]=>354, [2015, 7]=>382,
  #    [2015, 8]=>427, [2015, 9]=>433} 
h.update(h) { |_,v| round_to_nearest(v, 5) }
  #=> {[2015, 4]=>90, [2015, 5]=>225, [2015, 6]=>355, [2015, 7]=>380,
  # [2015, 8]=>425, [2015, 9]=>435} 

 def previous((year, month))
  month -= 1
  (year -=1; month = 12) if month.zero?
  [year, month]
end

def round_to_nearest(n, d)
  d*(n/d.to_f).round
end

如果我误解了这个问题,请告诉我(例如,您可能打算在数据库中这样做)。 如果是这样,我会修改或删除我的答案。

暂无
暂无

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

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