【问题标题】:Complex queries using Rails query language使用 Rails 查询语言的复杂查询
【发布时间】:2010-05-25 22:32:23
【问题描述】:

我有一个用于统计目的的查询。它分解了已登录给定次数的用户数量。用户 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,但想知道如何在 rails 3 中解决这个问题。

【问题讨论】:

    标签: ruby-on-rails activerecord ruby-on-rails-3 arel


    【解决方案1】:
    # 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 计数分组? 归根结底,我只想问你为什么不计算所有安装的总登录次数,因为用户信息与最外面的计数分组无关。

    【讨论】:

    • 谢谢。真正的问题是如何做到这样的事情。最后,我只是想处理一些更有趣的案例,而不是按名字找人。
    【解决方案2】:

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

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

    【讨论】:

    • 我刚刚学到了一些关于 AR 映射到数据库视图的知识。有用的,谢谢:)
    • 这是一个有趣的想法。我会再调查一下。
    【解决方案3】:

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

    【讨论】:

    • 只是因为学习曲线很长并不意味着它不值得学习。自从 arel 出来后,我再也没有写过 SQL,对此我感到非常高兴。
    猜你喜欢
    • 2013-05-22
    • 2017-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-24
    • 2013-08-17
    • 1970-01-01
    相关资源
    最近更新 更多