Сложные запросы с использованием языка запросов Rails - PullRequest
4 голосов
/ 26 мая 2010

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

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.

Ответы [ 3 ]

6 голосов
/ 26 мая 2010
# 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])

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

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

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

2 голосов
/ 26 мая 2010

Я не думаю, что вы найдете что-нибудь столь же эффективное, как если бы БД выполнял работу.Помните, что вам не нужно извлекать строки из базы данных, вы хотите, чтобы сама база данных вычисляла ответ, группируя данные.может создать запрос в виде представления в базе данных, а затем использовать класс Rails ActiveRecord для получения результатов.

0 голосов
/ 15 июля 2010

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

...