6

年齢層ごとにユーザー数を一覧表示しようとしています。

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

助言がありますか?

4

2 に答える 2

7

次のような 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それらのオブジェクトにはメソッドが含まnage_rangeます。そこからハッシュが必要な場合は、次のようにします。

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

もちろん、そこに人がいない範囲は含まれません。それは読者の演習として残しておきます。

于 2012-08-23T20:21:36.907 に答える