2012-04-01 83 views
0

我有一个任务模型,具有像created_at,小时和不同状态,我想按月汇总并总结不同的状态。按单个表上的查询进行分组总结

| Month | Count | Hours | States 
| 2012-01 | 22 | 26.5 | new(3), closed(4), others(15) 
| 2012-02 | 12 | 16.5 | new(0), approved(2), closed(9), others(1) 
... 

当前我正在使用此查询按月分组,并给我数+小时。

@tasks = Task.select("date(created_at), count(id), sum(hours) AS hours") 
      .group("MONTH(created_at)") 
      .order('created_at') 

我如何在所有不同的状态上添加总和?

我已阅读关于group_by,但我不认为这是很好的结果。

更新

有了这样我得到了几乎是我想要的查询。

@tasks = Tasks.select("date(created_at), state, count(state), sum(hours) AS hours") 
      .group("MONTH(created_at)") 
      .group("state") 
      .order('created_at') 

| Month | Count | Hours | State 
| 2012-01 | 3  | 26.5 | new 
| 2012-01 | 4  | 16.5 | approved 
| 2012-01 | 15 | 22.5 | others 
| 2012-02 | 2  | 16.5 | approved 
| 2012-02 | 9  | 16.5 | closed 
... 

UPDATE2

我有一个SQL查询,让我结果,我需要。

@tasks = Task.select(" 
    DATE(created_at) AS month, 
    COUNT(state), 
    SUM(hours) AS hours, 
    COUNT(case when `state` = 'new' then `state` else NULL end) AS state_new, 
    SUM(case when `state` = 'new' then `hours` else NULL end) AS state_new_hours, 
    COUNT(case when `state` = 'approved' then `state` else NULL end) AS state_approved, 
    SUM(case when `state` = 'approved' then `hours` else NULL end) AS state_approved_hours, 
    COUNT(case when `state` = 'closed' then `state` else NULL end) AS state_closed, 
    SUM(case when `state` = 'closed' then `hours` else NULL end) AS state_closed_hours, 
    COUNT(case when `state` != 'new' AND `state` != 'approved' AND `state` != 'closed' then `state` else NULL end) AS state_misc") 
.group("MONTH(created_at)") 
.order('created_at') 

这可以通过加入来完成吗?如何以更常用的导轨方式来处理这种情况,并具有动态状态使用情况?

+0

您是否拥有一组固定的状态 - 因此只有'新','封闭','其他'可能,或者它们是否会增长? – Vapire 2012-04-01 17:17:59

+0

它可能获得新的状态,但我知道它们。所以某种固定的。 – tonymarschall 2012-04-01 17:31:26

回答

1

所以,我假设你使用MySQL和你有一个单独的states表,并在其他列的状态由ID引用,就像这样:

| ID | Name | 
| 1 | new | 
| 2 | closed | 
| 3 | open | 

通过执行此SQL在MySQL声明

SELECT states.name AS state, DATE_FORMAT(tasks.created_at, '%Y-%m') AS month, 
     COUNT(tasks.id) AS count, SUM(tasks.hours) AS hours 
    FROM states JOIN tasks ON states.id = tasks.state_id 
GROUP BY state, month 
ORDER BY month 

你应该得到的结果是这样

| state | month | count | hours | 
| open | 2012-03 | 22 | 38.5 | 
| open | 2012-04 | 17 | 40.0 | 
| closed | 2012-03 | 45 | 0.5 | 

因此,您只需将此查询带入ActiveRelation查询,或者您可以使用Task.find_by_sql。 这与您描述的结果并不完全相同,但是使用此集合,您可以在执行后使用普通红宝石进行更改...

+0

感谢您的回答。我的状态与任务类似。我更新了我的问题,并添加了另一个几乎可以满足我需要的查询。 – tonymarschall 2012-04-01 18:24:52