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
创建的Users
, grouped
created_at
ordered
和grouped
,以及每天的此类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)
记得将hash
与hash1
合并而不是反过来,因为我们想要将hash
的value
从hash
重写为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 。