2013-02-09 45 views
1

不知道为什么这让我如此难倒,但我无法弄清楚如何去做。在Rails3中每天选择平均不同的值3

我有一个包含五十万个会话的表,并且需要从一开始就获得每天不同的mac地址的平均数。

我已经试过这样:

def self.average_users_per_day 
    self.average("distinct mac", :group => Chronic.parse("starttime")) 
end 

(使用慢性因为开始时间与时区的字符串..有没有和DATE(“开始时间)试过)

在大的数据集,我得到了我认为是正确的身影,直到我进行了一些测试,发现它不是真正的分组结果。

it "finds the average sessions per day", :focus => true do 
    10.times do 
    FactoryGirl.create(:session, starttime: Time.now, mac: (1..6).map{"%0.2X"%rand(256)}.join(":")) 
    end 

    10.times do 
    FactoryGirl.create(:session, starttime: Time.now - 1.days, mac: (1..6).map{"%0.2X"%rand(256)}.join(":")) 
    end 
    Session.average_users_per_day.to_i.should eq 10 
end 

结果总是20而不是10

查询应该是什么样子?任何帮助表示赞赏 - 有一个思想障碍。

+0

您希望mac在前10次与下一次10次会话相同? – 2013-02-09 17:10:40

+0

不,应该有10个不同的mac。每天10次平均课程。我失去了它?! – simonmorley 2013-02-09 19:24:03

+2

我想知道为什么你在测试中没有得到错误。你的average_users_per_day实现应该返回一个散列,所以调用.to_i给它应该会产生一个错误 – jvnill 2013-02-10 03:24:28

回答

2

你可能不得不在分组函数上工作,因为它不清楚wh在STARTIME确切的存储格式,但是这应该为你工作:

def self.average_users_per_day 
    self.from("(SELECT COUNT(DISTINCT mac) AS macs FROM #{self.quoted_table_name} GROUP BY DATE(startime)) AS counts").average("macs").to_f 
end 

刚开始使用MySQL的一个类似的模式测试,似乎工作。

+0

Blimey,看起来很有趣。谢谢,我以后会玩一玩。 – simonmorley 2013-02-10 11:12:03

+0

看起来应该可以工作,但测试仍然显示平均计数为20,而不是10.不确定逻辑是否正确。 – simonmorley 2013-02-10 19:21:20

1

我不完全确定这一点,但不知道你是否需要在SQL中解析日期而不是之后用Chronic解析日期,并且认为arel的平均值会返回值的有序散列,因此这是我尝试,我觉得作品,虽然使用SQLite具体SUBSTR函数提取从时间字符串

def self.average_users_per_day 
    sessions_per_day = self.select('distinct mac').group('substr(starttime, 0,11)').size.values 
    sessions_per_day.inject(:+).to_f/sessions_per_day.size 
end 

同样的日期,这将返回一个float等纷纷调整了规范到:

Session.average_users_per_day.should eq 10.0 
+0

OH。所以它不像以前想象的那么简单?我会用mysql给它一个镜头。谢谢 – simonmorley 2013-02-09 22:06:01

+0

这根本不起作用。回到绘图板。 – simonmorley 2013-02-10 00:03:08

+0

对不起,这完全不适合你,@mikeonrails的更优雅的答案也适用于我,但是他指出,在你的时间字符串上一天得到分组是一个问题。我希望看到你的解决方案。 – 2013-02-10 11:00:35