使用 Rails 查询语言的复杂查询

发布于 2024-09-02 18:39:37 字数 672 浏览 5 评论 0原文

我有一个用于统计目的的查询。它细分了已登录给定次数的用户数量。用户 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.

I have a query used for statistical purposes. It breaks down the number of users that have logged-in a given number of times. User has_many installations and installation has a 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 |
+--------+-------+

Is there some elegant ActiveRecord style find to obtain this same information? Ideally as a hash collection of logins and users: { 2=>3, 6=>7, ...

I know I can use sql directly but wanted to know how this could be solved in rails 3.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

傲娇萝莉攻 2024-09-09 18:39:38
# 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 中,因此要小心 count(
)

为什么要按total_login 计数进行分组?
归根结底,我只想问为什么不计算所有安装的总登录次数,因为最外层的计数分组使用户信息变得无关紧要。

# 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])

Keep in mind this is VERY verbose because I wanted to show you the order of operations not just the "Here is the code". The code can actually be written with half the code.

The hairy part is Count()
As a rule, any attribute in the SELECT that is not used in an aggregate should appear in the GROUP BY so be careful with count(
)

Why would you group by the total_login count?
At the end of the day I would simply ask why don't you just do a count of the total logins of all installations since the user information is made irrelevant by the outer most count grouping.

¢好甜 2024-09-09 18:39:38

我认为您不会发现任何事情比让数据库完成工作更有效。请记住,您不想从数据库中检索行,您希望数据库本身通过对数据进行分组来计算答案。

如果要将 SQL 进一步推送到数据库中,可以将查询创建为数据库中的视图,然后使用 Rails ActiveRecord 类来检索结果。

I don't think you'll find anything as efficient as having the db do the work. Remember that you don't want to have to retrieve the rows from the db, you want the db itself to compute the answer by grouping the data.

If you want to push the SQL further into the database, you can create the query as a view in the database and then use a Rails ActiveRecord class to retrieve the results.

不必在意 2024-09-09 18:39:38

最后,在我看来,SQL 语法更具可读性。当我只需要一点点复杂性时,这些 arel 的东西总是让我慢下来。这只是你学到的另一种语法,在我看来不值得。在这些情况下我会坚持使用 SQL。

In the end imo the SQL syntax is way more readable. This arel stuff is just slowing me down all the time when I only need just a tiny bit more complexity. It's just another syntax you have learn, not worth it imo. I'd stick to SQL in these cases.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文