如何分组过去20天并进行汇总功能?

时间:2013-03-25 14:57:55

标签: ruby-on-rails postgresql

我似乎无法想出这个。我试图获得过去20天的列标准偏差。这就是我所拥有的

Model.where('date < ?','2013-03-25')
     .group('date')
     .order('date DESC')
     .limit(20)
     .select('stddev_samp(percent_change) as stdev')

然而,我得到的只有20个Nil条目。我期待标准差的一次输入。

将stddev_samp切换为sum之后,我发现因为你不能在1个条目上产生标准偏差,所以我得到了nil。即它没有像我预期的那样对20进行分组,而是在每个日期计算标准偏差。

所以我的问题是,如何获得过去20天的stddev?我知道可以简单地选择select percent_change然后计算ruby中的标准差,但我假设在这种情况下聚合函数stddev_samp应该可用。

我正在使用rails 3.2和Postgresql 9.2

3 个答案:

答案 0 :(得分:1)

我不是Ruby人,所以我会在普通的SQL中解释它:

您正在做的是:

SELECT stddev_samp(percent_change) as stdev
FROM tbl
WHERE date < '2013-03-25'
GROUP BY date
ORDER BY date DESC
LIMIT 20;

这会分别计算每一天的偏差,而不是它们的总和,当你试图得到只有一个元素的偏差时,你会得到NULL。 删除GROUP BY会修复它,但也会返回整个表的结果,而不仅仅是最后20个条目,所以我们需要一个子查询:

SELECT stddev_samp(percent_change) as stdev
FROM
(SELECT percent_change
FROM tbl
WHERE date < '2013-03-25'
ORDER BY date DESC
LIMIT 20) AS q

答案 1 :(得分:1)

无需'分组依据','排序依据'或子选择。只需获取过去20天的记录并在其上运行聚合函数。

红宝石:

Model.where('date >= ?', Date.today - 20.days).select('stddev_samp(percent_change) as stdev').first['stdev']

SQL:

select stddev_samp(percent_change) as stdev 
from <table> 
where date >= now() - interval 20 day;

如果您想使用最后20个记录,而不是过去20天:

红宝石:

Model.order('date desc').limit(20).select('stddev_samp(percent_change) as stdev').first['stdev']

SQL:

select stddev_samp(percent_change) as stdev 
from <table> 
order by date desc
limit 20;

答案 2 :(得分:0)

您不需要该组,因为您不希望每个日期都有一个值。

如果您有多个日期值或缺少日期

,您的限制也可能无效

试试这个:

SELECT stddev_samp(percent_change) as stdev
FROM
(SELECT percent_change
FROM tbl
WHERE date > now() - interval '20 days') AS q