Rails 4 where,order,group,count包括零 – postgresql

这是我的查询:

User.where("created_at >= ? AND created_at <=?", date1,date2).order('DATE(created_at) DESC').group("DATE(created_at)").count 

我输出为:

 {Thu, 15 May 2014=>1} 

但我想在剩下的时间里将输出设为0。 对于前者

 {Thu, 15 May 2014=>1,Fri, 15 May 2014=>0} 

我想得到的是在date range创建的Usersgrouped created_at orderedgrouped ,以及每天的此类Users数。 如果特定日期没有用户,则应返回0,当前查询不返回。

我同意Himesh

试试这个:

 User.where("created_at >= ? AND created_at <=?", date1,date2).order('DATE(created_at) DESC').group("DATE(created_at)").count 

哪个会给:

 {Thu, 15 May 2014=>1} 

获取日期范围作为哈希初始化为0:

 hash1 = Hash[(date1..date2).collect { |v| [v, 0] }] 

现在合并两个哈希:

 hash = hash1.merge(hash) 

记得将hashhash1合并而不是反过来,因为我们想要将hashvaluehash重写为hash1

也许,这有点困难,好像任何用户都没有在5月16日创建,然后将没有5月16日的记录,因为数据库中的created_at和查询结果组不会包含5月16日的任何值。

可能你必须在ruby中处理这个问题。 或者您可以做的是检查特定日期是否作为hash_result中的键存在,如果它不存在则默认情况下用户计数为0。

希望这可以帮助 :)

虽然它似乎并不为人所熟知,但Ruby哈希具有“默认值”function,可以帮助您以更好的方式完成所需的操作。 另一种表达你想要做的事情的方式是:

创建一个散列,为我的数据范围内的任何键赋予0 ,除非我在该键下存储了一些其他值。

您可以使用块来完成此操作以建立哈希的默认值:

 @data = Hash.new do |h, key| if (date1..date2).include?(key) 0 else nil end end 

或者,更简洁:

 @data = Hash.new {|h, key| (date1..date2).include?(key) ? 0 : nil } 

然后从数据库加载数据并将其合并到此哈希中:

 @data.merge! User.where(…).group(…).count 

注意:您的order()无关紧要,因为您正在进行分组。 它可能会被优化掉,但您可以简单地将其关闭并获得相同的结果。

现在如果你做@data[foo]

  • 如果foo与日期无法比较,那么你将获得nil
  • 如果foo超出日期范围,你将获得nil
  • 如果foo在日期范围内但查询没有返回任何数据,则会得到0
  • 如果foo是数据库中包含数据的日期,您将获得正确的计数

此方法优于预加载哈希,因为即使对于非常大的日期范围,它也能有效地(在时间和空间上)。 而且可以说它也更直截了当。

我为此创建了一个gem – 查看Groupdate 。