ruby如何按给定日期分组

时间:2016-02-09 12:09:53

标签: ruby-on-rails ruby ruby-on-rails-4

我想每天查找注册计数,因为本月的日期范围。所以

starts_at = DateTime.now.beginning_of_month
ends_at = DateTime.now.end_of_month

dates = ((starts_at.to_date)..(ends_at.to_date)).to_a
dates.each_with_index do |date,i|
    User.where("created_at  >= ? and created_at <= ?", date, date.tomorrow)
end

如此运行近30个查询,如何避免运行30个查询并在单个查询中执行?

我需要像

这样的东西
group_by(:created_at)

但是在分组中,如果特定日期没有数据,则表示什么都没有,但我需要日期并计为0

我跟着这个:

How do I group by day instead of date?

def group_by_criteria
  created_at.to_date.to_s(:db)
end

User.all.group_by(&:group_by_criteria).map {|k,v| [k, v.length]}.sort

输出

  

[[“2016-02-05”,5],[“2016-02-06”,12],[“2016-02-08”,6]]

2016-02-05没有数据,所以它应该包括在计数0

2 个答案:

答案 0 :(得分:3)

我目前无法对其进行测试,但应该可以过滤您的日期范围并在dbms的帮助下对其进行分组,如下所示:

User.select('DATE(created_at)').where("created_at >= ? and created_at <= ?", DateTime.now.beginning_of_month, DateTime.now.end_of_month).group('DATE(created_at)').count

答案 1 :(得分:0)

这会吗?

starts_at = DateTime.now.beginning_of_month
ends_at = DateTime.now.end_of_month
User.where(created_at: starts_at..ends_at).group("date(created_at)").count
# => {Tue, 09 Feb 2016=>151, Mon, 08 Feb 2016=>130}

请注意,如果创作为零,您将无法获得任何日期结果,因此您可能希望执行以下操作:

Hash[*(starts_at..ends_at).to_a.flat_map{|d| [d, 0]}].merge(
  User.where(created_at: starts_at..ends_at).group("date(created_at)").count
)

不太好,但是你会发生什么事情,你首先创建一个散列,其中所有日期都在零值范围内,并将数据库中的结果合并到该散列中。