Группировать по годам, месяцам и затем считать в ActiveRecord 3 - PullRequest
9 голосов
/ 12 декабря 2011

Я пытаюсь получить количество всех пользователей, созданных за год и месяц, но, похоже, следующее не работает должным образом.

User.group("YEAR(created_AT), MONTH(created_at)").
     count("DISTINCT(id), YEAR(created_at), MONTH(created_at)")

Я ищу что-то вроде

{2011 => {1 => 222, 2 => 333, 4 => 444, 5 => 667 ... }}

но я получаю

{1 => 222, 2 => 333, 4 => 444, 5 => 667 ... }

Я что-то упустил или ActiveRecord не может дать мне этот результат в одном запросе?

1 Ответ

14 голосов
/ 12 декабря 2011

Метод count не работает так, как вы думаете.В итоге вы делаете это:

select count(distinct(id), year(created_at), month(created_at))
from users
group by year(created_at), month(created_at)

Это предложение SELECT довольно хитроумно, но MySQL, как обычно небрежно, пропустит его.Я думаю, что вы хотите этот запрос:

select count(distinct(id)), year(created_at), month(created_at)
from users
group by year(created_at), month(created_at)

Я бы, вероятно, сразу пошел к select_all как это:

a = User.connection.select_all(%q{
    select count(distinct(id)) as c, year(created_at) as y, month(created_at) as m
    from users
    group by y, m
})

Или вы могли бы сделать это так:1015 *

Это даст вам массив, a, хэшей с ключами c, y и m, например:

a = [
    { 'c' => '23', 'y' => '2010', 'm' => '11' },
    { 'c' => '1',  'y' => '2011', 'm' =>  '1' },
    { 'c' => '5',  'y' => '2011', 'm' =>  '3' },
    { 'c' => '2',  'y' => '2011', 'm' =>  '4' },
    { 'c' => '11', 'y' => '2011', 'm' =>  '8' }
]

Затем немного спор данныхэто все, что вам нужно, чтобы закончить работу:

h = a.group_by { |x| x['y'] }.each_with_object({}) do |(y,v), h|
    h[y.to_i] = Hash[v.map { |e| [e['m'].to_i, e['c'].to_i] }]
end
# {2010 => {11 => 23}, 2011 => {1 => 1, 3 => 5, 4 => 2, 8 => 11}} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...