2010-05-25 4 views
4

У меня есть запрос, используемый для статистических целей. Он разбивает количество пользователей, которые регистрировались в определенное количество раз. У пользователя has_many установки и установка есть login_count.Сложные запросы с использованием языка запросов Rails

select total_login as 'logins', count(*) as `users` 
    from (select u.user_id, sum(login_count) as total_login 
      from user u 
       inner join installation i on u.user_id = i.user_id 
       group by u.user_id) g 
    group by total_login; 

+--------+-------+ 
| logins | users | 
+--------+-------+ 
| 2  |  3 | 
| 6  |  7 | 
| 10  |  2 | 
| 19  |  1 | 
+--------+-------+ 

Есть некоторые элегантный стиль ActiveRecord find, чтобы получить эту же информацию? В идеале как набор хэш-логинов и пользователей: { 2=>3, 6=>7, ...

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

ответ

6
# Our relation variables(RelVars) 
U =Table(:user, :as => 'U') 
I =Table(:installation, :as => 'I') 

# perform operations on relations 
G =U.join(I) #(implicit) will reference final joined relationship 

#(explicit) predicate = Arel::Predicates::Equality.new U[:user_id], I[:user_id] 
G =U.join(I).on(U[:user_id].eq(I[:user_id]) 

# Keep in mind you MUST PROJECT for this to make sense 
G.project(U[:user_id], I[:login_count].sum.as('total_login')) 

# Now you can group 
G=G.group(U[:user_id]) 

#from this group you can project and group again (or group and project) 
# for the final relation 
TL=G.project(G[:total_login].as('logins') G[:id].count.as('users')).group(G[:total_login]) 

Имейте в виду, что это очень многословны, потому что я хотел бы показать вам порядок операций не только «Вот код». На самом деле код может быть написан с половиной кода.

Волосатый часть Count () Как правило, любой атрибут в SELECT, который не используется в совокупности должно появиться в GROUP BY, поэтому будьте осторожны со счетом ()

Почему бы вам группы по счету total_login? В конце дня я бы просто спросил, почему бы вам просто не подсчитать общее количество логинов всех установок, поскольку информация пользователя не имеет отношения к внешней группировке count.

+0

Спасибо. Реальный вопрос заключался в том, как можно было бы сделать что-то подобное. Ультимативно, я просто пытаюсь разобраться в некоторых более интересных случаях, кроме поиска кого-то по имени. –

2

Я не думаю, что вы найдете что-нибудь, как эффективный, поскольку db выполняет работу. Помните, что вы не хотите извлекать строки из db, вы хотите, чтобы db сам вычислил ответ, объединив данные.

Если вы хотите добавить SQL в базу данных, вы можете создать запрос как представление в базе данных, а затем использовать класс Rails ActiveRecord для получения результатов.

+0

Я только что кое-что узнал о AR-сопоставлении с представлением db. Полезно знать, спасибо :) – tsdbrown

+0

Это интересная идея. Я посмотрю на это немного больше. –

0

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

+0

только потому, что существует длинная кривая обучения, это не значит, что это не стоит изучать. Поскольку isl отсутствует, я никогда больше не писал SQL, и я очень этому рад. –

Смежные вопросы