ruby-on-rails – 按年龄范围分组用户在ruby中

我正在尝试按年龄范围列出用户数量
Range  : #Users
10-14  : 16
15-21  : 120
22-29  : 312
30-40  : 12131
41-70  : 612
71-120 : 20

我在考虑创建一个静态的哈希数组:

AGE_RANGES = [
  {label:"10 - 14",min:10,max:14},{label:"15 - 21",min:15,max:21},{label:"22 - 29",min:22,max:29},{label:"30 - 40",min:30,max:40},{label:"41 - 70",min:41,max:70},{label:"71 - 120",min:71,max:120}
]

然后将其用于我的搜索过滤器以及我的查询.但是,我想不出能从中获得最大性能方法.

我的模型中的方法仅按年龄分组:

def self.group_by_ageRange(minAge,maxAge)

  query = User.group("users.age")
              .where("users.age BETWEEN minAge and maxAge ")
              .select("users.age,count(*) as number_of_users")

end

有什么建议?

解决方法

您想构建一些如下所示的sql
select count(*),case
           when age between 10 and 14 then '10 - 14'
           when age between 15 and 21 then '15 - 21'
           -- ...
       end as age_range
from users
where age between 10 and 120
group by age_range

在ActiveRecord术语中,这将是:

# First build the big ugly CASE,we can also figure out the
# overall max and min ages along the way.
min   = nil
max   = nil
cases = AGE_RANGES.map do |r|
    min = [r[:min],min || r[:min]].min
    max = [r[:max],max || r[:max]].max
    "when age between #{r[:min]} and #{r[:max]} then '#{r[:min]} - #{r[:max]}'"
end

# Then away we go...
age_ranges = Users.select("count(*) as n,case #{cases.join(' ')} end as age_range")
                  .where(:age => min .. max)
                  .group('age_range')
                  .all

这将为您提供age_ranges中的对象数组,这些对象将具有n和age_range方法.如果你想要哈希,那么:

age_ranges = Hash[age_ranges.map { |r| [r.age_range,r.n] }]

那当然不包括那些没有任何人的范围;我将把它作为读者的练习.

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...