2012-08-04 75 views
1

我在執行計算,爲計算值應用條件並在一個查詢中計算結果。問題是我不知道如何從條件中引用計算的字段。ruby​​計算字段的活動記錄條件

我有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不適用於我。

回答

0

我發現了一個example of code這實際上幫助:

ActiveRecord doesn't have a parameter for including a HAVING clause in your database queries and I sometimes find myself needing it. Luckily, you can sneak it in on the end of your :group parameter without needing to resort to a find_by_sql() call. (I don't recall ever using HAVING without GROUP BY, though there probably are some cases where it would make sense to do so.)

As an example, here's a query from one of my Rails applications that finds all duplicate email addresses in the database:

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) 
0

你應該這樣做:

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

它更清晰。

+0

好了,但我應該怎麼跟做的方式那部分? :只讀=> true – savvadia 2012-08-04 17:41:54

+0

您可以在最後添加只讀。它工作更好嗎? – Dougui 2012-08-04 18:16:07

+0

我問過,因爲我只是不知道如何做到這一點......我看到過像select(),where(),group()這樣的命令,但不是像readonly()這樣的onr命令。所以你可以給我一行代碼。 – savvadia 2012-08-04 19:50:31