计算字段的ruby活动记录条件

时间:2012-08-04 12:34:09

标签: ruby activerecord count conditional-statements

我尝试执行计算,为计算值应用条件并在一个查询中统计结果。问题是我不知道如何从条件中引用计算字段。

我有Issues.created_on字段,我想查找有关用户提供的一周内每周创建的问题数量的统计信息。 这是我的查询在MySql中的样子:

mysql>  SELECT status_id as group_id,
YEAR(created_on)*1000+WEEK(created_on,1) as range_value, count(*) as
noOfEntries FROM `issues` WHERE (`issues`.`project_id` IN (1))  GROUP
BY issues.status_id, range_value;

+----------+-------------+-------------+
| group_id | range_value | noOfEntries |
+----------+-------------+-------------+
|        1 |     2012031 |           2 |
|        5 |     2012015 |           1 |
+----------+-------------+-------------+

这是我的代码(简化):

# Range value is dynamic: "YYYYXXX", where YYYY is year and XXX could be week, month or day of year
range_value = "YEAR(created_on)*1000+WEEK(created_on,1)"    
select = "#{range_value} as range_value, count(*) as noOfEntries"
grouping = "range_value"
# other conditions are provided by user, so we just add one here
conditions["range_value"] = range[:min]..range[:max]

rows = Issue.all(:select => select, :conditions => conditions, :readonly => true, :group => grouping)

但是我收到了这个错误:

ActiveRecord::StatementInvalid (Mysql::Error: Unknown column 'issues.range_value' in 'where clause': SELECT YEAR(created_on)*1000+WEEK(created_on,1) as range_value, 'weeks' as range_type, count(*) as logged_hours, 1 as entries, 'priority_id' as grouping, issues.priority_id as group_id FROM `issues` WHERE (`issues`.`range_value` BETWEEN '2012012' AND '2012031' AND `issues`.`project_id` IN (1))  GROUP BY range_value, issues.priority_id ORDER BY 1 asc, 6 asc):

我尝试修改的代码不是我的代码,因此我无法向Issues对象添加任何新字段或方法。因此,我认为像this这样的解决方案对我不起作用。

2 个答案:

答案 0 :(得分:0)

你应该这样做:

rows = Issue.select(select).where(conditions).group(grouping).readonly

更清楚。

答案 1 :(得分:0)

我找到了example of code实际上有所帮助:

  

ActiveRecord没有包含HAVING子句的参数   您的数据库查询,我有时发现自己需要它。幸运的是,   你可以在你的:group参数的末尾偷偷摸摸它   需要求助于find_by_sql()调用。 (我不记得曾经使用过   没有GROUP BY,虽然可能有一些情况   这样做是有意义的。)

     

作为示例,这是来自我的一个Rails应用程序的查询   查找数据库中所有重复的电子邮件地址:

duplicates = User.find( :all,
  :select     => "email, COUNT(email) AS duplicate_count",
  :conditions => "email IS NOT NULL AND email != ''",
  :group      => "email HAVING duplicate_count > 1"
)

经过稍作修改后,我的代码就可以了:

# Range value is dynamic: "YYYYXXX", where YYYY is year and XXX could be
# week, month or day of year
range_value = "YEAR(created_on)*1000+WEEK(created_on,1)"    
select = "#{range_value} as range_value, count(*) as noOfEntries"
# CHANGED THIS LINE from: grouping = "range_value"
grouping = " HAVING range_value BETWEEN #{range[:min]} AND #{range[:max]}"

# other conditions are provided by user, so we just add one here
# REMOVED THIS LINE
# conditions["range_value"] = range[:min]..range[:max]

rows = Issue.all(:select => select, :conditions => conditions, :readonly => true, :group => grouping)